동일한 항목의 데이터가 여러 파일로 나누어져 있을때 하나의 파일로 병합

 

다음 에제코드는 [CSV] 여러개의 CSV파일 처리 - 1의 CSV파일의 데이터를 하나의 CSV파일로 병합하는 코드

 

 

 

- 코드설명 -

 


 13       with open(output_file, 'a', newline='') as csv_out_file:


 

13행

- 출력파일을 open하는 with문

- open()함수의 인수로 'w'가 아닌 'a' 사용하여 추가모드(append)로 파일 open

- 쓰기모드('w'): 이전에 처리된 출력 파일의 데이터를 덮어쓰기

- 추가모드('a'): 이전에 처리된 출력파일의 맨 끝라인에 추가하여 쓰기

 


 17          if is_first_file:

               ...

 21          else:

 22             header = next(freader)

               ...


 

17행~25행

- if-else문은 9행에서 생성한 is_first_file 변수를 이용해 첫 번째 입력 파일과 후속 입력파일을 구분

- 헤더 행은 최종 출력 파일에 한번만 기록 되도록 하기 위함

- 17행~20행 if문 블록은 첫 번째 입력 파일을 처리하도록 하여 헤더행 포함

- 21행~25행 else문 블록은 나머지 모든 입력 파일을 처리하도록 하기 위해 출력파일에 기록하기전 22행의 next() 함수를 활용한 header처리 구문 포함

 

(*) 출력파일 r_merge_out_csv_files.csv를 통해 결과 확인

(*) 소스코드 및 csv 파일 첨부

 

 

11_소스코드 및 CSV파일.zip

Posted by Roiz
,

대부분의 프로젝트에서는 하나의 파일이 아닌 여러개의 파일 활용

여러개의 CSV파일로부터 행과 열의 개수 확인

 

다음 예제코드는 현재폴터('./')에 있는 여러개의 CSV파일의 개수와 각 CSV파일의 행, 열의 개수를 세어 화면에 출력해주는 코드

 

 

 

 

 

- 코드설명 -


   3 import glob

   4 import os


 

3행

- glob 모듈 임포트

- glob모듈을 이용해 특정 패턴과 일치하는 모든 경로명을 탐색 가능

- 패턴에는 * 등 유닉스 쉘 스타일의 와일드카드 문자 포함 가능

- 본 예제에서는 8행에 서 '2017*'를 이용, 2017로 시작하는 파일명을 갖는 모든 파일을 검색

- 읽어오는 CSV파일은 파일명이 모두 2017로 시작되는 파일임, 확장자가 csv인 모든파일을 검색하고자 한다면 8행에 '2007*'을 '*.csv'로 변경하면 가능

4행

- os 모듈 임포트

- 경로명을 파싱하는데 유용한 함수 포함

- os.path.basename(path)는 입력받은 경로에서 파일명 반환

 


  9 for input_file in glob.glob(os.path.join(input_path, '2007*')):


 

9행

- 여러개의 입력파일에서 데이터를 처리하기 위한 핵심

- glob 및 os모듈의 함수를 사용하여 처리할 입력파일의 리스트를 생성하고 for문으로 일련의 입력파일을 반복

- os.path.join() 함수는 괄호 안에 있는 두개의 컴포넌트를 결합

- input_path는 입력 파일이 들어있는 폴더의 경로

- '2007*'는 2007 패턴으로 시작하는 파일의 이름을 나타냄

- glob모듈의 glob.glob()함수는 '2007*'의 별표(*)를 실제 파일명으로 확장

- 이 예제에서 glob.glob()과 os.path.join()은 다섯개의 입력파일이 들어있는 리스트 생성

 


 17    print('{0!s}: \t{1:d} rows \t{2:d} columns'.format(\

 18           os.path.basename(input_file), row_counter, len(header)))


 

17,18행

- 각 입력 파일의 파일이름, 파일의 행과 열의 수를 출력하는 print문

- 세개의 열(파일명, 행수, 열수)를 정렬하기 위해 탭 문자(\t) 삽입

- {}문자를 사용해 세개의 값을 print문에 전달

- 첫번째 값: os.path.basename()함수를 이용해 전체 경로명의 마지막요소(파일명)를 추출

- 두번째 값: 변수 row_counter 를 이용해 각 입력 파일에서 행의 개수 추출

- 세번째 값: len()함수를 이용해 각 입력파일의 열 헤더가 들어있는 리스트변수(header)의 원소 개수를 추출

 

 


 19 print('Number of files: {0:d}'.format(file_counter))


 

19행

- file_counter의 값을 사용하여 스크립트에서 처리한 파일의 개수를 출력

 

 

(*) 결과화면

 

(*) 소스코드 및 CSV파일 첨부

 

10_소스코드 및 CSV파일.zip

 

Posted by Roiz
,

CSV 파일에 불필요한 열이 포함되어있는 경우, 필요한 열만 필터링하여 활용

- 열의 인덱스 값을 사용하는 방법

- 열의 헤더를 사용하는 방법

 

열의 헤더를 사용해 특정(관심) 열을 필터링

- 관심있는 열 헤더를 쉽게 식별가능

- 여러개의 입력 파일을 처리할 때 열의 헤더는 같지만 열의 위치가 입력 파일에 따라 다를 때

 

다음 예제 코드는 [CSV] 열의 인덱스 값을 사용하여 특정열을 선택 에서와 동일하게 Name 및 BOD, TN, T-P열만 사용하기 위한 필터링을 헤더명을 이용해 수행

 

 

 

 

- 코드설명 -

 


  7 selected_column_name = ['Name', 'BOD', 'T-P', 'TN']

  8 selected_column_index = [ ]


 

7행

- 관심있는 헤더명이 들어있는 리스트변수(selected_column_name) 생성

8행

- 뒤에서 관심열의 인덱스값이 들어갈 리스트변수(selected_column_index) 생성

 

 


 14       next(freader)

 15       header = next(freader)

 16       for index_value in range(len(header)):

 17          if header[index_value] in selected_column_name:

 18             selected_column_index.append(index_value)

 19       print(selected_column_name)

 20       fwriter.writerow(selected_column_name)


 

14행

- freader객체에 next()함수를 사용하여 헤더에서 사용되지 않는 행 삭제

15

- freader객체에 next()함수를 사용하여 헤더에서 사용되는 행을 header 리스트변수로 읽어옴

16행

- header 리스트변수로 읽어온 헤더의 인덱스 값에 대해 반복문 수행

17행

- if문과 리스트 인덱싱을 통해 각 열의 헤더가 관심 헤더명과 동일한 값인지 판별

- header[index_value]가 selected_column_name과 같다면 18행 수행 그렇지 않다면 for문으로...

18행

- 17행에서 판별한 값이 포함되어있는 index_value값을 selected_column_index리스트 변수에 추가

19, 20행

- 관심있는 헤더를 화면과 파일로 출력

 


 21       for row_list in freader: 

 22          row_list_output = []

 23          for index_value in selected_column_index

 24             row_list_output.append(row_list[index_value])

 25          print(row_list_output)

 26          fwriter.writerow(row_list_output)


 

21행

- 헤더를 제외한 CSV파일의 값에 대해 for문 수행

22행

- 포함하려는(관심있는)행의 데이터 값을 저장할 빈 리스트(row_list_output) 생성

23행

- selected_column_index의 값을 반복

24행

- 23행의 인덱스 값에 해당하는 열의 데이터 값을 row_list_output에 추가

25, 26

- row_list_output의 값을 화면 및 파일에 출력

 

(*) 출력파일 로 설정한 r_filtering_by_column_name.csv를 통해 결과 확인

(*) 소스코드 파일 첨부(csv파일은 [CSV] 파일 읽고 쓰기(2) 에...)

 

 

7_filtering_by_column_name.zip

Posted by Roiz
,

CSV 파일에 불필요한 열이 포함되어있는 경우, 필요한 열만 필터링하여 활용

- 열의 인덱스 값을 사용하는 방법

- 열의 헤더를 사용하는 방법

 

열의 인덱스 값을 이용해 특정 열을 필터링

- 열의 인덱스 값을 쉽게 식별가능

- 여러개의 입력 파일 처리 하기 위한 모든 입력 파일에서 열의 위치가 변경되지 않는 경우

 

다음 예제 코드는 Name 및 BOD, TN, T-P 열만 사용하기 위해 인덱스 값을 이용한 필터링 수행

 

 

 

 

- 코드설명 -

 


  8 selected_columns = [1, 6, 9, 10]


 

8행

- CSV에서 추출하려는 4열의 인덱스 값을 갖는 selected_column 리스트변수 생성

 


 14       for row_list in freader:

 15          row_list_output = []

 16          for index_value in selected_column:

 17             row_list_output.append(row_list[index_value])

 18          print(row_list_output)

 19          fwriter.writerow(row_list_output)


 

15

- CSV에서 추출하고자 하는 각 행의 값을 저장하기 위한 row_list_output 리스트변수 생성

16행

- selected_column에 저장되어있는 관심 인덱스 값을 반복하는 for문

17행

- 리스트의 append()함수를 사용해 selected_column에 정의된 특정 인덱스의 데이터 값을 row_list_output에 추가

- fwriter의 writerow()함수는 문자열이나 숫자의 시퀀스 자료형을 받으므로 리스트변수(row_list_output)를 만들어 놓는것이 유용함

18, 19행

- row_list_output의 값을 화면 및 파일에 출력

 

(*) 출력파일 로 설정한 r_filtering_by_column_index.csv를 통해 결과 확인

(*) 소스코드 파일 첨부(csv파일은 [CSV] 파일 읽고 쓰기(2) 에...)

 

6_filtering_by_column_index.zip

 

Posted by Roiz
,

특정한 패턴과 일치하거나 패턴(정규표현식)이 포함되어있는 행에 대한 필터링

 

다음 예제 코드는 어떤 행의 값이 특정 패턴과 일치하는지 판별, 패턴과 일차하는 값을 갖는 행의 데이터셋 출력

- 데이터셋에서 Date열의 데이터 값이 5열이후에 '-04-'를 포함하는 모든행을 필터링

 

 

 

 

 


   3 import re


 

3행

- re모듈(정규 표현식 모듈)의 함수를 사용할 수 있도록 re 모듈 import

 


   8 pattern = re.compile(r'(?P<my_pattern_group>^....-04-.*)', re.I)


 

8행

- re모듈의 compile() 함수를 사용해 정규 표현식 변수(pattern) 생성

- r은 작은 따옴표 사이의 패턴이 원시 문자열임을 나타냄

- 메타문자 ?P<my_pattern_group> 는 <my_pattern_group>그룹에 포함되어있는 하위 문자열 필터링

- 본 예제의 패턴은 ^....-04-.* 임

- 캐럿(^)은 문자열이 시작하는 패턴을 검색

- 마침표(.)는 개행을 제외한 임의 문자 하나를 나타냄

- 별표(*)는 메타 문자 앞에 있는 문자가 0번이상 일치해야함을 나타냄

- 따라서 ^....-04-.* 는 개행문자를 제외한 임의문자 4개로 시작하고 5~8열은 -04- 이고 이후 개행문자를 제외한 모든 문자가 몇번이든 올수 있다는 의미

- 즉, 04월에 해당하는 모든 행을 필터링 하라는 의미

- re.I 인수는 정규 표현식이 대소문자를 구분하지 않음

 


 19          date = row_list[2]

 20          if pattern.search(date):

 21             print(row_list)

 22             fwriter.writerow(row_list)


 

19행

- 리스트 인덱싱을 이용해 csv파일에서 Date열을 추출하고 이를 date변수에 할당

20행

- re 모듈의 search 함수를 이용해 date변수에 할당된 값을 앞서 정의한 패턴으로 필터링

21, 22행

- 필터링된 패턴을 화면과 파일로 출력

 

(*) 출력파일로 설정한 r_filtering_value_match_pattern.csv를 통해 결과확인

(*) 소스코드 첨부(csv 파일은 [CSV]파일 읽고 쓰기(2) 에서 확인가능....)

 

5_filtering_value_match_pattern.zip

Posted by Roiz
,

관심 대상 집합을 포함하는 행을 필터링

- Name열에서 집합 ['kyungan3', 'kyungan5']중 한 값을 포함하는 모든 행

- Date열에서 집합 ['2007-06-04', '2007-11-13']중 한 값을 포함하는 모든 행

 

다음 예제 코드는 행의 데이터 값이 어떤 집합의 원소를 포함하는지 판별하고, 전체 행에서 관심집합의 값을 포함하는 행들(부분집합)을 찾아 화면 및 파일로 출력

 

 

 

 

- 코드설명 -

 


  7 #important_dates = ['2007-06-04', '2007-11-13', '2007-12-12']

  8 important_stations = ['kyungan3', 'kyungan5']


 

8행(7행)

- 관심값에 해당하는 name을 important_stations 변수에 리스트형(type)으로 할당

 


 19          #a_date = row_list[2]

 20          a_name = row_list[1]

 21          #if a_date in important_dates:

 22          if a_name in important_stations:

 23             print(row_list)

 24             fwriter.writerow(row_list)


 

20행(19행)

- freader로 읽은 csv 파일의 각 행에서 name열(row_list[1])을 로드하여 a_name변수에 할당

( - freader로 읽은 csv 파일의각 행에서 date열(row_list[2])을 로드하여 a_date변수에 할당 )

22행(21행)

- if 문을 사용해 a_name 변수에 들어있는 name 열의 데이터 값이 important_stations 에 있는 관심 집합에 포함되는지 판별

( - if 문을 사용해 a_date 변수에 들어있는 date 열의 데이터 값이 important_date에 있는 관심 집합에 포함되는지 판별 )

23행, 24행

- 22행의 판별결과로 a_name가 important_stations에 포함된다면, 화면 및 파일에 출력

 

(*) 주석 처리된 부분을 기존 코드와 대체하면 - 관심값을 name에서 date로 변경하여 필터링

 

 

 

(*) 출력파일로 설정한 r_filtering_value_in_set.csv를 통해 결과 확인

(*) 소스코드 첨부(csv파일은 [CSV]파일 읽고 쓰기(2) 에서 확인가능...)

 

4_filtering_value_in_set.zip

 

Posted by Roiz
,

특정 조건에 부합하는 행의 값을 판별하고, 조건에 충족하는 행을 필터링

 

 

 

다음 예제 코드는 두가지 조건(Name이 'kyungan3' 이고 TDJG가 '1000' 이상인 행)을 판별하고, 조건을 충족하는 행으로 구성된 데이터셋을 화면 및 파일로 출력

 

 

- 코드설명 -

 


 11     next(freader) 

 12     header=next(freader) 

 13     print(header)

 14     fwriter.writerow(header)


 

 

11행

- csv모듈의 next() 함수를 사용하여 입력파일의 의미없는(?) 첫번째 행을 삭제

12행

- csv모듈의 next() 함수를 사용하여 입력파일의 두번째 행을 리스트변수 header에 할당

13행

- print() 함수를 사용하여 헤더 행을 화면에 출력

14행

- 헤더 행을 파일에 출력

 


 16       station_name = str(row_list[1]).strip()

 17       TDJG = str(row_list[13]).strip().replace(',','')

 18       if station_name == 'kyungan3' and float(TDJG) > 1000.0:

 19         print(row_list)

 20         fwriter.writerow(row_list)


 

16행

- 각 행의 Name열에 해당하는 값을 가져와 station_name 변수에 할당

- 리스트 인덱싱(row_list[1])을 사용하여 각 행의 두번째 열(Name열)의 로드

str() 함수를 사용하여 값을 문자열로 반환

strip() 함수를 이용해 문자열의 양끝에서 공백, 탭, 개행문자 등 제거

17행

- 각 행의 TDJG열에 해당하는 값을 가져와 TDJG 변수에 할당

- 리스트 인덱싱(row_list[13])을 통해 각 행의 14번째 열(TDJG열)의 값 로드

- str() 함수를 사용하여 값을 문자열로 반환

- strip() 함수를 이용해 문자열의 양끝에서 공백, 탭, 개행문자 등 제거

- replace() 함수를 이용해 1000단위 쉼표 제거

18행

- 각 행의 값들이 두가지 조건에 부합하는지 판별(if문)

- station_name이 'kyungan3' 이면서 TDJG값이 1000 이상인 행을 필터링

- 두가지 조건에 모두 부합하는 행을 선별하여 조건에 맞는다면 if문 내부코드 수행

19행, 20행

- 두 조건에 모두 부합하는경우 수행되며

- 필터링된 row_list를 화면과 파일에 각각 출력

(*) 16행 ~ 20행은 for 반복문으로 csv파일 전체열에 대하여 수행

 

(*) 출력파일로 설정한 'filtering_value_meet_condition.csv'를 통해 결과 확인

(*) 소스코드 파일 첨부(csv파일은 [CSV] 파일 읽고 쓰기(2) 에...)

 

 

3_filtering_value_meet_condition.zip

 

 

Posted by Roiz
,