CSV๋ ?
๋ฐ์ดํฐ ๋ถ์์์ ๊ฐ์ฅ ํํ ์ ํ๋ ํ์ ์ค ํ๋๊ฐ CSV(Comma Separated Values) ํ์ผ์ด๋ค. CSV๋ ๋ฐ์ดํฐ๊ฐ ์ผํ(๋๋ ๋ค๋ฅธ ๊ตฌ๋ถ์)๋ก ๊ตฌ๋ถ๋ ํ ์คํธ ํ์์ผ๋ก ์ ์ฅ๋๋ค. Pandas์ read_csv() ํจ์๋ ์ด๋ฌํ ํ์ผ์ ๊ฐ๋จํ ์ฝ์ด๋ค์ผ ์ ์๋๋ก ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ฒ ๊ธ์์๋ CSV ํ์์ ๋ํ ๊ฐ๋จํ ์๊ฐ์ ํจ๊ป Pandas๋ก CSV ํ์ผ์ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ, ์์ฃผ ์ฌ์ฉํ๋ ์ฃผ์ ๋งค๊ฐ๋ณ์, ๊ทธ๋ฆฌ๊ณ ์๋ฌ๋ฅผ ์๋ฐฉํ๊ฑฐ๋ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๋๋ก ํ๊ฒ ๋ค.
CSV ํ์ผ ํ์์ด๋ ?
CSV ํ์ผ์ ๋ฐ์ดํฐ๊ฐ ์ผํ(,)๋ก ๊ตฌ๋ถ๋์ด ์ ์ฅ๋ ๋จ์ํ ํ ์คํธ ํ์ผ์ด๋ค. ๊ฐ ํ์ ๋ฐ์ดํฐ์ ํ ๋ ์ฝ๋๋ฅผ ๋ํ๋ด๋ฉฐ, ์ฒซ ๋ฒ์งธ ํ์ ์ผ๋ฐ์ ์ผ๋ก ์ด ์ด๋ฆ(ํค๋)์ผ๋ก ์ฌ์ฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ๋ค.
# CSV ํ์ผ ์์
# Name,Age,City
# Alice,25,New York
# Bob,30,Los Angeles
# Charlie,35,Chicago
CSV ํ์ผ์ ํน์ฑ
- ๊ตฌ๋ถ์: ์ผ๋ฐ์ ์ผ๋ก ์ผํ(,)๋ก ๊ตฌ๋ถ๋์ง๋ง, ํญ(\t) ๋๋ ์ธ๋ฏธ์ฝ๋ก (;)์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ์๋ค.
- ํค๋: ์ฒซ ๋ฒ์งธ ํ์ ์ด ์ด๋ฆ์ด ํฌํจ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
- ํ ์คํธ ์ธ์ฝ๋ฉ: ๊ธฐ๋ณธ์ ์ผ๋ก utf-8์ด ์ฌ์ฉ๋์ง๋ง, ํ๊ตญ์์๋ cp949๋ euc-kr๋ก ์ ์ฅ๋ ํ์ผ๋ ํํ ์ฌ์ฉ๋๋ค.
Pandas๋ก CSV ํ์ผ ๋ถ๋ฌ์ค๊ธฐ
Pandas์ read_csv() ํจ์๋ CSV ํ์ผ์ DataFrame์ผ๋ก ๋ณํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
# pandas๋ ์ฃผ๋ก `pd`๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ถ๋ฌ์์ ์ฌ์ฉํ๋ค.
import pandas as pd
# CSV ํ์ผ ์ฝ๊ธฐ
df = pd.read_csv('data.csv')
# DataFrame ์ถ๋ ฅ
print(df)
์ ์ฝ๋๋ ํ์ฌ ๋๋ ํฐ๋ฆฌ์ ์๋ 'data.csv' ํ์ผ์ ์ฝ์ด DataFrame์ผ๋ก ๋ณํํ ํ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ค.
์ฃผ์ ๋งค๊ฐ๋ณ์ (Parameters)
read_csv()๋ ๋ค์ํ ์ต์ ์ ์ ๊ณตํ์ฌ ํ์ผ์ ๊ตฌ์กฐ์ ๋ง๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์๋ค. ์์ฃผ ์ฌ์ฉํ๋ ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
# index_col
# DataFrame์์ ํน์ ์ด์ ์ธ๋ฑ์ค๋ก ์ค์ ํ ์ ์๋๋ก ๋์์ค
# ์ธ๋ฑ์ค(index)๋ ๋ฐ์ดํฐ์ ๊ณ ์ ํ ์๋ณ์ ์ญํ ์ ํ๋ฉฐ, ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ฒ์๊ณผ
# ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํจ
df = pd.read_csv('data.csv', index_col=0) # ์ฒซ ๋ฒ์งธ ์ด์ ์ธ๋ฑ์ค๋ก ์ค์
# sep
# ๊ตฌ๋ถ์๋ฅผ ์ง์ ํ๋ฉฐ, default๋ ์ผํ(,)
df = pd.read_csv('data.tsv', sep='\t') # ํญ(tab)์ผ๋ก ๊ตฌ๋ถ๋ ํ์ผ ์ฝ๊ธฐ
# encoding
# ํ
ํธ์ค ํ์ผ์ ๋ฌธ์ ์ธ์ฝ๋ฉ์ ์ง์ ํจ
# ๊ธฐ๊ด์์ ์ ๊ณตํ๋ ๋ฐ์ดํฐ์ encoding ํ์์ `cp949`์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์
# default๋ `utf-8` ํ์
df = pd.read_csv('data.csv', encoding='cp949') # `cp949`๋ก ์ธ์ฝ๋ฉ๋ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
# header
# ํค๋(์ด ์ด๋ฆ)์ด ์๋ ํ ๋ฒํธ๋ฅผ ์ง์ ํ๋ค. default๋ 0(์ฒซ ๋ฒ์งธ ํ์ ๋ปํจ)
df = pd.read_csv('data.csv', header=None) # ํค๋ ์์ด ํ์ผ ์ฝ๊ธฐ
# na_values
# ํน์ ๊ฐ์ ๊ฒฐ์ธก๊ฐ(NaN, Not a Number)์ผ๋ก ์ฒ๋ฆฌ
# * ์ฐธ๊ณ ๋ก null์ ์กด์ฌํ์ง ์์์ ๋ปํ๋ฉฐ, NA๋ Not Available์ ์ค์๋ง
# ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ ๊ฐ์ NaN์ผ๋ก ํด์๋จ : " ", "#N/A", "#N/A N/A", "#NA", "-1.#IND",
# "-1.#QNAN", "-NaN", "-nan", "1.#IND", "1.#QNAN", "<NA>", "N/A", "NA", "NULL",
# "NaN", "None", "n/a", "nan", "null "
df = pd.read_csv('data.csv', na_values=['N/A', '-'])
# usecols
# ์ฝ๊ณ ์ ํ๋ ์ด๋ง ์ ํํจ
df = pd.read_csv('data.csv', usecols=['Name', 'Age'])
์๋ฌ ์๋ฐฉ ๋ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ
1) ParserError
ํ์ผ์ ๊ตฌ๋ถ ๋ถ์ํ๋ ๋์ ์ด์ ๊ฐ์๊ฐ ๋ง์ง ์์ ๋ฐ์ํ๋ ์๋ฌ์ ๋๋ค. ์๋ฅผ ๋ค์ด
pandas.errors.ParserError: Error tokenizing data. C error: Expected 6 fields in line 13, saw 7
13๋ฒ์งธ ์ค์์ 6๊ฐ์ ํ๋ ๊ฐ์ด ์์ด์ผ ํ๋๋ฐ 7๊ฐ์ ๊ฐ์ด ์์ด ๋ฐ์ํ๋ ๋ฌธ์ . ํด๋น ๋ผ์ธ์๋ง ๋ฌธ์ ๊ฐ ์์ ์ ์์ผ๋, ๋ ๋ง์ ํ์์ ๋ฌธ์ ๊ฐ ์์ ์ ์์ผ๋ฏ๋ก ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ํ์ 'skip'์ผ๋ก ๊ฑด๋๋ฐ๋๊ฒ ํ๋์ ๋ฐฉ๋ฒ์ผ์๋ ์๋ค.
# error_bad_lines
# Pandas 1.3.0 ์ด์ ๋ฒ์ ์์ ์ง์
# ์ด ์ต์
์ ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ๋๋ ํ์ ๊ฑด๋๋ฐ๊ณ ๋๋จธ์ง ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ฌ ์ ์์
df = pd.read_csv('data.csv', error_bad_lines=False) # ๋ฌธ์ ๊ฐ ๋๋ ํ ๊ฑด๋๋ฐ๊ธฐ
# on_bad_lines
# Pandas 1.3.0 ์ดํ ๋ฒ์ ์์ ์ง์
# ์ต์ Pandas์์๋ on_bad_lines ์ต์
์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๊ฐ ๋๋ ํ์ ์ฒ๋ฆฌํ ์ ์์
# on_bad_lines ์ต์
# 'error': ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐ์์ํด (default)
# 'skip': ๋ฌธ์ ๊ฐ ๋๋ ํ์ ๊ฑด๋๋
# callable ํจ์: ํน์ ํ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง ์ฌ์ฉ์ ์ ์ ํจ์๋ก ์ง์
df = pd.read_csv('data.csv', on_bad_lines='skip') # ๋ฌธ์ ๊ฐ ๋๋ ํ ๊ฑด๋๋ฐ๊ธฐ
# skiprows
# ๋ฌธ์ ๊ฐ ๋๋ ํ์ด ํน์ ํ ๋ฒํธ์ ์์นํด ์๋ค๋ฉด ํด๋น ์ต์
์ ์ฌ์ฉํด
# ๋ช
์์ ์ผ๋ก ๊ฑด๋๋ธ ์ ์์
df = pd.read_csv('data.csv', skiprows=[2, 4]) # ํน์ ํ ๊ฑด๋๋ฐ๊ธฐ (์: 2, 4๋ฒ ํ ๊ฑด๋๋ฐ๊ธฐ)
# ๋ฌธ์ ๊ฐ ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ํํฐ๋ง ๋ฐ์ดํฐ ํ์ผ์ ํฌ๊ธฐ๊ฐ ํฌ๊ฑฐ๋ ํ์ ์์น๋ฅผ ๋ฏธ๋ฆฌ ์ ์ ์๋ ๊ฒฝ์ฐ,
# ๋ฐ์ดํฐ๋ฅผ ํ ์ค์ฉ ์ฝ์ผ๋ฉด์ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ํํฐ๋งํ๋ ๋ฐฉ์๋ ์ฌ์ฉํ ์ ์์
# ์ด๋ฅผ ์ํด Pandas์ `chunksize`๋ฅผ ์ฌ์ฉํจ
# ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ ๋จ์๋ก ์ฝ๊ธฐ
valid_rows = []
for chunk in pd.read_csv('data.csv', chunksize=1000):
# ํํฐ๋ง ์กฐ๊ฑด ์ ์ฉ (์: ์ด ๊ฐ์๊ฐ ๋ง๋ ํ๋ง)
valid_chunk = chunk[chunk.apply(lambda x: len(x) == len(chunk.columns), axis=1)]
valid_rows.append(valid_chunk)
# ์ ํจํ ํ๋ค๋ก ๋ฐ์ดํฐํ๋ ์ ์์ฑ
df = pd.concat(valid_rows, ignore_index=True)
2) ์ธ์ฝ๋ฉ ๊ด๋ จ ๋ฌธ์
ํ๊ตญ์ด ํ์ผ์ `utf-8` ๋์ `cp949` ๋๋ `euc-kr`๋ก ์ ์ฅ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์, ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 0: invalid start byte
ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก๋ `encoding` ํ์์ ๋ช ์์ ์ผ๋ก ์ง์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋๋ค.
# encoding='cp949' ๋๋ encoding='euc-kr'๋ฅผ ์ง์
df = pd.read_csv('data.csv', encoding='cp949')
# or
df = pd.read_csv('data.csv', encoding='euc-kr')
# ๋ฐ์ดํฐ ์ ์ฅ ์ `utf-8-sig`ํ์ ์ฌ์ฉ
df.to_csv('output.csv', index=False, encoding='utf-8-sig')
# utf-8 : ๋๋ถ๋ถ์ ์ด์ ์ฒด์ ์์ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์ธ์ฝ๋ฉ ๋ฐฉ์
# utf-8-sig : utf-8์ BOM(Byte Order Mark)์ ์ถ๊ฐํ์ฌ Windows์ Linux ๋ชจ๋์์ ํธํ์ฑ์ ๋ณด์ฅ
'๊ฐ๋ฐ Code > ํ์ด์ฌ Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Python][numpy] Numpy ๋ฐฐ์ด ์ ์ฅ ๋ฐ ๋ถ๋ฌ์ค๊ธฐ (0) | 2025.02.09 |
---|---|
[Python][numpy] Numpy ๊ธฐ์ด๋ถํฐ ํ์ฉ๊น์ง (0) | 2025.02.08 |
[Python][pandas] ๋ฐ์ดํฐ ์ ๋ ฌํ๊ธฐ - Sort (0) | 2025.01.30 |
[Python][pandas] ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ - Excel (1) | 2025.01.22 |
[Python][pandas] pandas ํบ์๋ณด๊ธฐ (0) | 2025.01.22 |