Python で CSV ファイルを操作する
Python を使ってcsvファイルの読み書きをする方法を述べる。
なお、ここでは NumPy や pandas は用いない。
環境は Ubuntu 18.04、Python 3.6.9 である。
最初に。やりがちなミス
ファイル名をcsv.pyにするな!
最初に言いますが、ありがち失敗ですが、これから作るPythonファイル名を csv.py にしてはいけません。
してしまうと、
import csv
が自身をインポートしようとして結果うまくいかなくなってしまいます。
結果、例えばcsv.writerを呼び出すと以下のようなエラーがでます。
AttributeError: module 'csv' has no attribute 'reader'
別の名前にしましょう! (同じディレクトリにcsv.pyというファイルがあっても当然ダメなのでちゃんと消しましょう)
csvファイルの作成
まずはcsvファイルを作成しましょう。
writerow という関数で簡単に書けます。
csv_test.py
#!/usr/bin/env python3
import csv
def create_csv():
with open('sample.csv', 'w') as f:
w = csv.writer(f)
w.writerow([0, 'aaa', 'あああ'])
w.writerow([1, 'bbb', 'いいい'])
w.writerow([2, 'ccc', 'ううう'])
if __name__ == '__main__':
create_csv()
with を使っていますが勝手にファイルをcloseしてくれるので、ファイル操作時は with を積極的に用いましょう。
実行するとsample.csvができているはずです。
$ python3 csv_test.py
$ cat sample.csv
0,aaa,あああ
1,bbb,いいい
2,ccc,ううう
csvファイルの読み込み
・行の読み込み
#!/usr/bin/env python3
import csv
def read_csv():
with open('sample.csv', 'r') as f:
r = csv.reader(f)
for row in r:
print(row)
if __name__ == '__main__':
read_csv()
これによりsample.csvを先頭から一行づつ読みます。
・行の各値の読み込み
行を読み込んだのは良いですが、各項目の値を読むにはどうしたらよいでしょうか?
単純にrow[0]やrow[1]のように配列番号で読めば良いだけです。
#!/usr/bin/env python3
import csv
def read_csv():
with open('sample.csv', 'r') as f:
r = csv.reader(f)
for row in r:
print("{} {} {}".format(row[0], row[1], row[2]))
if __name__ == '__main__':
read_csv()
・タイトルラベルの読み飛ばし
csvファイルにタイトル行がある場合を読み飛ばしたいと思います。
要望が多いのでしょう、1行読み飛ばす next() という関数が用意されています。
(むろん先頭だけじゃなく2回呼べば2行読み飛ばします)
まぁforループ内で最初の1行目読み飛ばせばいいだけなのですが、頻度の高い処理なのできっとだれかが関数化したのでしょう。
#!/usr/bin/env python3
import csv
def read_csv():
with open('sample2.csv', 'r') as f:
r = csv.reader(f)
next(r)
for row in r:
print(row)
if __name__ == '__main__':
read_csv()
csvファイルの書き込み
・行の追加
作成時にすでに書いていますが、csv.writer() で writerow()すれば良いです。
・行の削除
良い方法は何かあるんでしょうけど、基本作り直しです。10行目を消したいなら、10行目を読み飛ばした結果をcsvファイルとして出力することにより結果として削除する、という方法です。
・値の変更
各行の各列の値を直接変更出来たら楽なのですが標準のAPIでは存在していません。
ので、行レベルでの書き換えになるでしょう。しかしながら行の挿入もできませんのでやはりcsvファイルを最初から作り直しです。
大きなcsvファイルをcsvの標準機能で扱うのはちょっと面倒な気がしました。NumPyやpandasは便利なのがあるのでしょうけど。
以上!