메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

파이썬 데이터 분석 입문

파이썬 데이터 분석 입문 07, 패턴/정규 표현식을 활용한 필터링

한빛미디어

|

2017-12-08

|

by 클린턴 브라운리

3,028

기본 파이썬

특정한 패턴과 일치하거나 패턴이 포함되어 있는(즉, 정규 표현식) 행을 선택하여 하위 데이터셋으로 만들어야 하는 경우가 종종 있다. 예를 들어 가지고 있는 데이터셋에서 InvoiceNumber 열의 데이터 값이 001-로 시작하는 모든 행을 선택해야 하는 경우가 있을 수 있다. 또는 Supplier Name 열의 데이터 값에 Y가 포함되어 있는 모든 행을 원할 수도 있다. 이런 경우 행의 데이터 값이 패턴과 일치하는지 혹은 패턴을 포함하는지를 판별한 뒤, 그 행을 필터링한다.

 

다음 예제는 어떤 행의 값이 특정 패턴과 일치하는지를 판별하고, 패턴과 일치하는 값을 갖는 행의 하위 데이터셋을 출력 파일에 작성하는 방법을 보여준다. 이 예제에서는 InvoiceNumber 열의 데이터 값이 001-로 시작하는 행을 선택하고 결과를 출력 파일에 쓴다. 이 패턴과 일치하는 값을 가진 행의 하위 데이터셋을 필터링해보겠다. 텍스트 편집기에 다음 코드를 입력하고 파일명을 5csv_reader_value_matches_pattern.py로 저장한다.

 

#!/usr/bin/env python3

import csv

import re

import sys

input_file = sys.argv[1]

output_file = sys.argv[2]

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

with open(input_file, 'r', newline='') as csv_in_file:

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

    filereader = csv.reader(csv_in_file)

    filewriter = csv.writer(csv_out_file)

    header = next(filereader)

    filewriter.writerow(header)

    for row_list in filereader:

      invoice_number = row_list[1]

      if pattern.search(invoice_number):

        filewriter.writerow(row_list)

 

3행에서 re모듈(정규 표현식 모듈)의 함수에 접근할 수 있도록 re모듈을 임포트했다.

 

9행에서는 re모듈의 compile()함수를 사용하여 pattern이라는 이름의 정규 표현식 변수를 생성한다. 앞서 1장에서 정규 표현식에 대해서 살펴봤으므로 이 함수의 내용이 익숙할 것이다. 여기서 r은 작은따옴표 사이의 패턴이 원시 문자열임을 나타낸다.

 

?P<my_pattern_group>라는 메타 문자는 <my_pattern_group>이라는 그룹에 포함되어 있는 하위 문자열을 찾아내 필요한 경우에 화면에 출력하거나 파일에 기록할 수 있게 해준다. 우리가 찾는 실제 패턴은 ^001-.*이다. 캐럿(^)은 문자열이 시작하는 경우 패턴만 검색하는 특수 문자다. 즉 이 패턴은 001-로 시작하는 문자열만 찾는다. 마침표(.)는 개행을 제외한 임의의 문자 하나를 나타낸다. 따라서 개행을 제외한 모든 문자가 001- 뒤에 올 수 있다. 마지막으로 별표(*)는 메타 문자 앞에 있는 문자가 0번 이상 일치해야 함을 나타낸다. 따라서 .* 조합은 개행을 제외한 모든 문자가 001- 뒤에 몇 번이든 올 수 있다는 의미이다. 더 비공식적으로 말하면 - 뒤에는 어떠한 문자열이 와도 상관없으며, 001-로 시작한다면 그 길이 역시 상관없다.

 

마지막으로 re.I 인수는 정규 표현식이 대/소문자를 구분하지 않고 찾도록 지시한다. 이 예제에서는 패턴이 숫자이므로 이 인수가 덜 중요하지만, 패턴에 문자가 포함되어 있고 대/소문자를 구분하지 않고 찾는 경우 이 예제처럼 두 번째 인수로 지정해야 한다.

 

18행에서는 리스트 인덱싱을 사용하여 행에서 Invoice Number열을 추출하고 이를 invoice_number라는 변수에 할당했다. 다음 행에서는 이 변수에 포함된 패턴을 찾을 것이다. 19~20행은 re모듈의 search 함수를 사용하여 invoice_number에 저장된 값의 패턴을 찾는다. 해당 패턴이 invoice_number의 데이터 값에 들어 있으면 그 행을 출력 파일에 쓴다.

 

스크립트를 실행하려면 명령 줄에 다음을 입력하고 엔터 키를 누른다.

 

python 5csv_reader_value_matches_pattern.py supplier_data.csv 5output.csv

 

그다음 출력 파일인 5output.csv를 열어 결과를 확인할 수 있다.

 

 

팬더스

팬더스를 이용하여 특정 패턴과 일치하는 값을 가진 행을 필터링해보겠다. 텍스트 편집기에 다음 코드를 입력하고 파일명을 pandas_value_matches_pattern.py로 저장한다. 이 스크립트는 CSV 파일을 읽고 패턴과 일치하는 값을 가진 행을 화면에 출력한 다음 출력 파일에 기록한다.

 

#!/usr/bin/env python3

import pandas as pd

import sys

 

input_file = sys.argv[1]

output_file = sys.argv[2]

 

data_frame = pd.read_csv(input_file)

data_frame_value_matches_pattern = data_frame.ix[data_frame['Invoice Number']\

  .str.startswith("001-"), :]

data_frame_value_matches_pattern.to_csv(output_file, index=False)

 

 

팬더스 예제에서는 startswith() 함수를 사용하여 정규 표현식을 사용하지 않고 데이터를 찾아냈다.(역주_ 앞의 기본 파이썬 예제 역시 정규 표현식 대신 startswith() 함수를 사용할 수 있다.) 스크립트를 실행하려면 명령 줄에 다음을 입력하고 엔터 키를 누른다.

 

python pandas_value_matches_pattern.py supplier_data.csv pandas_output.csv

 

그다음 출력 파일인 pandas_output.csv를 열어 결과를 확인할 수 있다.

댓글 입력
자료실