해당 내용은 Datacamp의 Data engineering track을 정리했습니다.
Streamlined Data Ingestion with pandas의 chapter 1에 대한 내용입니다.
해당 포스팅에는 아래의 내용을 포함하고 있습니다.
- Pandas 소개, Flat File에 대한 설명, CSV 파일 불러오기
- read_csv의 다양한 argument 소개(usecols, nrows, skiprows, header, names)
- Flat Flie 불러올 때, 신경 써야 하는 부분
1. Introduction to flat files
Pandas는 파이썬에서 데이터 처리를 위해 많이 활용되는 라이브러리입니다. 다양한 형태의 파일을 불러오고 전처리할 수 있고 row와 column으로 이뤄진 2차원 데이터 구조를 가지고 있습니다. 기본적으로 Column은 attribute에 해당하며, row는 record를 의미합니다. 그래서 다양한 파일들을 불러올 수 있는 데 그중에 대표적인 CSV 파일이 강의에서 언급하고 있는 Flat File의 대표적인 파일 형태라고 보시면 됩니다. Flat File은 간단하고 쉬운 포맷으로 이뤄진 데이터입니다. 특별하게 다른 특별한 형태로 저장되는 경우는 없으며 row는 1개의 라인으로 작성됩니다. 또한 다양한 delimiter에 의해서 값들이 구분되는 데, Tab, space, comma 등으로 구분합니다. 대표적인 형태는 위에서 언급한 것처럼 csv가 있습니다. pandas에서 해당 파일들을 불러오기 위해서는 read_csv()라는 명령어를 통해서 불러올 수 있습니다.
위의 파일을 pandas로 읽어오기 위해서는 아래의 코드로 불러올 수 있습니다.
import pandas as pd #pandas 라이브러리 import
tax_data = pd.read_csv("us_tax_data_2016.csv") # 파일 불러오기
tax_data.head(4) # 불러온 파일의 위에서 4의 row까지 출력
위의 코드를 실행할 때에는 파일 위치를 정확하게 넣어주는 것이 중요합니다. 위의 예시의 경우 작업하는 파일과 csv파일이 동일한 위치에 있기 때문에 파일명으로도 접근이 가능했으나, 다른 위치에 있다면, 절대경로나 상대 경로를 통해서 파일을 불러와야 합니다.
위의 그림처럼 깔끔한 형태로 출력되는 것을 알 수 있습니다.
read_csv는 다양한 argument가 존재합니다. 위의 파일처럼 ","로 구분되어 있는 경우에는 read_csv만 사용해줘도 가능합니다. 하지만 공백으로 구분되어 있거나 Tab으로 구분되어 있는 경우에는 해당 값을 sep이라는 argument에 적용해줘야 합니다.
import pandas as pd
tax_data = pd.read_csv("us_tax_data_2016.tsv", sep='\t')
위의 예시코드를 보시면 파일의 확장자명이 tsv로 되어있습니다. 이는 tab으로 구분된 파일이라는 의미를 가지고 있습니다. 그래서 read_csv를 통해 tsv파일을 불러올 때에는 delimeter가 다르다는 것을 알려주기 위해 sep='\t'이라는 argument를 추가해줘야 잘 동작합니다. sep 외에도 다양한 argument가 존재하는 데 해당 자료는 아래 강의에서 소개합니다.
2. Modifying flat file imports
csv파일을 불러온 것의 행과 열의 개수를 확인하고 싶을 때에는 .shape를 통해 (row, column) 형태의 결과 값을 얻을 수 있습니다.
csv파일에서 필요한 column이 정해져 있을 때, 불필요한 column은 불러오지 않고 싶을 때가 있습니다. 그런 경우에는 usecols라는 argument를 통해서 원하는 column의 이름이나 index 번호를 지정해주면 해당 column만 불러올 수 있습니다.
col_names = ["STATEFIPS", "STATE", "zipcode", "agi_stub", "N1"]
col_nums = [0, 1, 2, 3, 4]
# Choose columns to load by name
tax_data_v1 = pd.read_csv("us_tax_data_2016.csv", usecols=col_names)
# Choose columns to load by number
tax_data_v2 = pd.read_csv("us_tax_data_2016.csv", usecols=col_nums)
# 2개의 데이터가 동일한 지 확인
print(tax_data_v1.equals(tax_data_v2)) # True
위의 코드처럼 이름과 index로 접근이 가능하며, 두 가지 방법으로 얻은 DataFrame의 경우 동일한 형태이기 때문에 마지막 명령어로 True가 나오는 것을 알 수 있습니다.
위에서는 column을 제한하는 방법을 알려드렸습니다. column을 제한한 것처럼 row의 개수도 제한할 수 있습니다. row의 limit을 제한하는 방법은 nrows라는 argument로 제한할 수 있습니다. nrows=1000을 넣어주면, 처음부터 1000개의 row만 살립니다.
nrows를 활용하면 앞에 불필요한 row가 있는 경우 건너뛰고 싶을 수 있습니다. 그런 경우에는 skiprows를 통해서 불필요한 row를 뛰어서 데이터를 받아올 수 있습니다. 일반적으로 csv파일의 최상단에 불필요한 row가 2개 정도 있을 때, skiprow를 활용하면 원하는 table만 불러올 수 있습니다.
read_csv를 통해 불러올 때, header가 설정되어 있지 않으면 보통 첫 줄을 column 이름으로 저장합니다. header=None일 경우에는 0, 1, 2, 3처럼 임의의 값으로 column 이름을 사용합니다. 첫줄에 있는 데이터도 데이터로 취급하게 됩니다. column의 이름을 정해서 바꿔주고 싶을 때에는 names라는 argument에 리스트 형태로 넣어주면 됩니다. 일부만 바꾸는 것은 import 한 뒤에 할 수 있습니다. names를 활용할 때에는 모든 행의 값을 넣어줘야 합니다.
3. Handling errors and missing data
Flat File은 import했을 때 공통적으로 발생하는 문제들이 있습니다. 하나는 데이터 타입이 잘못되어 있는 경우, 또 다른 하나는 값이 없는 경우입니다. 보통 pandas로 받은 데이터는 .dtypes라는 명령어를 통해서 각 column의 데이터 타입을 확인할 수 있습니다. 그리고 read_csv를 할 때, dtype={"칼럼명": 변경할 데이터 타입}으로 데이터 타입을 수정할 수 있습니다.
tax_data = pd.read_csv("us_tax_data_2016.csv", dtype={"zipcode": str})
print(tax_data.dtypes) #zipcode : object
보통 결측치는 데이터마다 다르게 나타날 수 있지만 우편번호의 경우 0으로 나오는 경우는 없기 때문에 이런 경우에 결측치 처리를 해줘야 합니다. 보통 na_values라는 argmument에 {"칼럼명": 0}으로 입력해주면, 해당 칼럼에 해당하는 0값은 결측치로 처리하게 됩니다.
마지막으로 File을 import할 때, 입력 오류에 의해서 제대로 파싱이 되지 않는 경우가 있습니다. 그런 경우에는 error_bad_lines=False로 처리해주면 문제가 있는 부분은 제외하고 파싱을 할 수 있습니다. 또한 경고 문구가 같이 나오게 되는데, 이런 경고 문구를 없애려고 한다면 warn_bad_lines=False로 지정해주면 됩니다.