【Python】 Python ~ 基本編 / CSV ~

■ はじめに

Pythonでの CSV の扱い方について、学ぶ

目次

【1】csv モジュールを使う
【2】pandas を使う
【3】Dask を使う
【AA】CSVあれこれ
【ZZ】トラブル

【1】csv モジュールを使う

例1:csv を読み込む

import csv

with open('hello.csv', 'r') as csv_file:
  reader = csv.reader(csv_file)
  # ヘッダー
  header = next(reader)
  print(header) # ['item1', 'item2', 'item3']

  print('*****')

  # Body
  for row in reader:
    print(row) # ['hello1', 'world1', 'Mike'] ...

hello.csv

item1,item2,item3
hello1,world1,Mike
hello2,world2,Tom
hello3,world3,Smith
hello4,world4,Kevin

例2:書き込み

import csv

with open('output.csv', 'w', newline="") as csv_file:
  writer = csv.writer(csv_file, delimiter="|")
  writer.writerow(["id", "name", "age"])
  writer.writerow(["001", "Mike", 29])

例3:io.StringIO

その1:CSV形式の文字列をパースする

import csv
import io

csv_data = """no,name,remarks
1,Mike,hello
2,Smith,World
3,Tom,!!!
"""

csv_reader = csv.reader(io.StringIO(csv_data))
# ヘッダー
header = next(csv_reader)
print(header)

print('*****')

# Body
for row in csv_reader:
  print(row)

その2:区切り文字を指定

import csv
import io

csv_data = 'abc|def|ghi|jkl|mno'

csv_reader = csv.reader(io.StringIO(csv_data), delimiter="|")
data = next(csv_reader)
print(data)
print(len(data))

【2】pandas を使う

Pandas の詳細は、以下の関連記事を参照のこと。

Pandas ~ 基本編 / CSV編 ~
https://dk521123.hatenablog.com/entry/2020/11/17/000000

例1:pandas

import pandas as pd

data_frame = pd.read_csv('hello.csv')
print(data_frame)
print(data_frame['item3'][0]) # Mike
for value in data_frame['item2']:
  print(value) # world1 ...

【3】Dask を使う

Dask については、以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2020/06/23/161204

例3:Daskを使用したサンプル

import dask.dataframe as dd

# CSV読み込み
ddf = dd.read_csv('hello.csv')

print(ddf.compute())
print("***************")
for row in ddf.itertuples():
  print(row.id)
  print(row.name)

# CSV書き出し
ddf.to_csv('out.csv')

hello.csv

id,name
1,Mike
2,Tom
3,Naomi

出力結果

   id   name
0   1   Mike
1   2    Tom
2   3  Naomi
***************
1
Mike
2
Tom
3

参考文献

https://qiita.com/lucky0707/items/ff8ce66a40c492945229
https://qiita.com/katsuki104/items/222a9d5e85e4f92f4c43

【AA】CSVあれこれ

区切り文字を変更したい場合

csv.reader() の delimiterを指定する。

https://docs.python.org/ja/3/library/csv.html#csv.reader
サンプル:区切り文字「|」の場合

import csv

with open('hello.csv', 'r') as csv_file:
  reader = csv.reader(csv_file, delimiter="|")

【ZZ】トラブル

エラー「_csv.Error: line contains NULL byte」が発生

発生コード

import csv

with open('sample.csv', 'r') as file:
  csv_reader = csv.reader(file)
  for csv_value in csv_reader: # ここで例外
    print(csv_value)

原因

対象ファイル内に、Nullコード '\0' があったため

解決策

以下に詳しく解説されている。感謝。

https://daily-fruit.com/programing/python/478/

with open('sample.csv', 'r') as file:
  # Nullコード '\0' を 空文字に変換
  csv_reader = csv.reader((line.replace('\0','') for line in file))

エラー「_csv.Error: field larger than field limit (131072)」が発生

原因

フィールド限界値 (131072) より大きいフィールドが指定されたため。
(ほぼエラーメッセージを和訳しただけ) 

解決策

import csv

# !! 追加 !!
csv.field_size_limit(2147483647)

with open('sample.csv', 'r') as file:
  csv_reader = csv.reader(file)

補足:sys.maxsizeについて
https://stackoverflow.com/questions/15063936/csv-error-field-larger-than-field-limit-131072

# にある「sys.maxsize」をそのまま入れた場合は、
# オーバーフローでエラーになる(少なくともWindows環境 / Python3 だと)

import sys
import csv

csv.field_size_limit(sys.maxsize)
# Error : OverflowError: Python int too large to convert to C long

参考文献
https://mokehehe.hatenadiary.org/entry/20110401/csv_field_size_limit

エラー「UnicodeDecodeError: 'charmap' codec can't decode byte X」発生

別にCSVに限った話ではないが...

エラー内容

UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to <undefined>

解決策

# , encodingを指定
with open('sample.csv', 'r', encoding="utf8") as file:
  csv_reader = csv.reader(file)

参考文献
https://stackoverflow.com/questions/9233027/unicodedecodeerror-charmap-codec-cant-decode-byte-x-in-position-y-character

参考文献

https://qiita.com/okadate/items/c36f4eb9506b358fb608
https://www.haya-programming.com/entry/2018/07/03/042203

関連記事

Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / ファイル読込・書込 ~
https://dk521123.hatenablog.com/entry/2019/10/07/000000
PythonExcel を扱うには
https://dk521123.hatenablog.com/entry/2019/11/05/221010
Pandas ~ 基本編 / CSV編 ~
https://dk521123.hatenablog.com/entry/2020/11/17/000000
Pythonメモリリークに関するあれこれ
https://dk521123.hatenablog.com/entry/2020/06/23/161204