WEBのシステム開発はPHPを使用していますが、データ解析等のため Python3 の研究を始めました。Python3 は日本語の情報がとても少ないので、エンジニアや学生の皆さんに役立ちそうなことをブログ記事として共有できればと思います。
この記事では Python3 で CSV の読み書きをする方法についてまとめました。CSV は Microsoft Excel(Windows) で読み書きされることがあるため、Shift_JIS による読み書きも載せてみました。
CSVの読み書き事始め
Python3 で CSV ファイルの読み書きをする方法は2通りあります。
- 標準モジュール csv を使う
- pandas ライブラリを使う
CSV ファイルの読み書き程度なら標準モジュールで十分なので、ここでは Python3 にはじめから組み込まれている標準モジュール( csv )を使います。pandas については下記の公式ドキュメントを参照ください。
csv モジュール公式ドキュメント
https://docs.python.jp/3/library/csv.html
pandas 公式ドキュメント
http://pandas.pydata.org/pandas-docs/stable/
CSV ファイルの書き出し
まずはサンプルから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 標準モジュール csv のインポート import csv try: # 書き込み UTF-8 with open('sample_person.csv', 'w') as csvfile: writer = csv.writer(csvfile, lineterminator='\n') writer.writerow(['連番ID', '姓', '名']) writer.writerow([1, '佐藤', '葵']) writer.writerow([2, '鈴木', 'さくら']) writer.writerow([3, '高橋', '陽菜']) # 書き込み Shift_JIS with open('sample_person_sjis.csv', 'w', encoding='shift_jis') as csvfile: writer = csv.writer(csvfile, lineterminator='\n') writer.writerow(['連番ID', '姓', '名']) writer.writerow([1, '田中', '大翔']) writer.writerow([2, '伊藤', '蓮']) writer.writerow([3, '渡辺', '悠真']) # 起こりそうな例外をキャッチ except FileNotFoundError as e: print(e) except csv.Error as e: print(e) |
とくに難しいことはないかと思いますが、いくつかポイントを。
1. with open を使う
Python3 でファイルの読み書きをする際には基本的に with open を使いましょう。with open を使っていれば、ファイルの open/close 時に予期せぬエラーが生じても Python が安全に処理してくれます。
2. 文字コード指定
open の際に文字コードを指定しない場合(デフォルト)は UTF-8 で書き出されます。Microsoft Excel で開きたいという要望がある場合には引数に encoding=’shift_jis’ を指定しましょう。それだけです。
PHP の場合には mb_convert_encoding 関数や mb_convert_variables 関数で文字コード変換を行うのが一般的ですが、Python3 の方がちょっとだけスマートですね。
3. エラー処理
CSV読み書きの際の例外処理は csv.Error で行うことができます。
CSV ファイルの読み込み
まずはサンプルから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 標準モジュール csv のインポート import csv try: # utf-8 のCSVファイル with open('sample_person.csv', 'r') as csvfile: csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"') for row in csv_reader: # print(row) print(','.join(row)) # utf-8 のCSVファイル - ヘッダ行をスキップ with open('sample_person.csv', 'r') as csvfile: csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"') next(csv_reader) # ヘッダ行をスキップ for row in csv_reader: print(','.join(row)) # shift-jis のCSVファイル with open('sample_person_sjis.csv', 'r', encoding='shift_jis') as csvfile: csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"') for row in csv_reader: print(','.join(row)) # 起こりそうな例外をキャッチ except FileNotFoundError as e: print(e) except csv.Error as e: print(e) |
いくつかポイントを。
1. ヘッダのスキップは next 関数
ヘッダ行をスキップする場合には next 関数を使うと良いでしょう。next 関数は Python の組み込み関数です。
https://docs.python.jp/3/library/functions.html#next
2. 文字コード
書き込みと同じです。UTF-8 の場合は指定しなくて良いですが、Shift_JIS の場合には open 関数の引数に encoding=’shift_jis’ を明示的に指定する必要があります。
文字コードが不明な場合 – 実践者向け
それなりの規模のプロジェクトとなれば、Shift_JIS の CSV もあれば UTF-8 のものもある…という状況は決して珍しくありません。
そのようなときには getenc モジュールの getenc.getEncode() でファイルの文字コード判定を行って、その文字コードを open 関数の引数として指定します。
1 2 3 4 5 6 7 8 9 10 11 |
import csv # getenc モジュールをインポート import getenc # 文字コードが不明な場合 enc = getenc.getEncode('unknown_enc.csv') with open('unknown_enc.csv', 'r', encoding=enc) as csvfile: csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"') for row in csv_reader: print(','.join(row)) |
以上、Python3 で CSV の読み書きする方法をまとめてみました。弊社の専門はPHP言語なので、おかしなところがあればご指摘ください。
※この記事の内容は適宜更新することがあります。