1: 2016-12-04 (日) 03:50:13 njf |
現: 2016-12-29 (木) 12:46:46 njf |
| *始めに [#xbdfb8a8] | | *始めに [#xbdfb8a8] |
| + | |
| + | 仕事などのデータをExcelやGoogleスプレッドシートなどでいただくことが多くあります。数百行ぐらいならそのまま使えますが、数千行とかになるとなかなか管理が難しくなってきます。 |
| + | |
| + | 毎回マクロなどで対応するのも大変なので、CSVに書き出ししてPythonでsqliteなどのデータベースに入れて管理したりしています。するとSQLが使えるので、集計などが自動化でき、かつ高速です。 |
| + | |
| + | 特にGoogleスプレッドシートの場合は、権限によってはCSVでダウンロードするところからPythonで処理することも可能なので、表示の重い画面を開かずに更新の有無などをチェックできて、管理するのがとても楽になります。 |
| + | |
| + | 以下でそんな時に必要となるPython2.7でのCSV処理について簡単にまとめます。 |
| | | |
| *CSVファイルの読み込み [#rf8c79ef] | | *CSVファイルの読み込み [#rf8c79ef] |
| + | |
| + | まず以下のテストファイルを「test.csv」という名前で用意したとします。 |
| + | |
| + | ID,name,comment |
| + | 1,山本,こんにちは |
| + | 2,松本,こんばんは |
| + | 3,中本,さようなら |
| + | |
| + | 文字コードはUTF-8を使って下さい。ファイル形式がそれ以外の場合はUTF-8に変換してから処理するのが無難です。 |
| + | |
| + | csvファイルの読み込みは以下のようにできます。 |
| + | |
| + | import csv |
| + | |
| + | f = open("test.csv") |
| + | |
| + | csvData = csv.reader(f) |
| + | |
| + | for row in csvData: |
| + | print row[0],row[1],row[2] |
| + | |
| + | f.close() |
| + | |
| + | 結果 |
| + | |
| + | ID name comment |
| + | 1 山本 こんにちは |
| + | 2 松本 こんばんは |
| + | 3 中本 さようなら |
| + | |
| + | 次の記法でも全く同じことができます。 |
| + | |
| + | import csv |
| + | |
| + | with open('test.csv', 'rb') as f: |
| + | reader = csv.reader(f) |
| + | for row in reader: |
| + | print row[0],row[1],row[2] |
| + | |
| + | 読み出しの型はstrになっています。 |
| + | |
| + | with open('test.csv', 'rb') as f: |
| + | reader = csv.reader(f) |
| + | for row in reader: |
| + | print type(row[1]) |
| + | 結果 |
| + | <type 'str'> |
| + | <type 'str'> |
| + | <type 'str'> |
| + | <type 'str'> |
| + | |
| + | 最初からUTF-8として読み込めないかとやってみましたが、エラーとなりました。 |
| + | |
| + | f = codecs.open("test.csv", 'r', 'utf_8') |
| + | csvData = csv.reader(f) |
| + | |
| + | for low in csvData: |
| + | print low[0],type(low[1]),low[2] |
| + | |
| + | f.close() |
| + | |
| + | 結果 |
| + | ID <type 'str'> comment |
| + | Traceback (most recent call last): |
| + | File "csvTest.py", line 15, in <module> |
| + | for low in csvData: |
| + | UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128) |
| + | |
| + | 読み込んだあとにUTF-8に変換すると良いでしょう。変換方法は「[[Python/Unicodeの取り扱い]]」を参照のこと。 |
| + | |
| + | 引用符で囲まれ、改行コードを含むようなデータにも対応しています。 |
| + | |
| + | test.csvを以下のように書き換えると、 |
| + | ID,name,comment |
| + | 1,山本,こんにちは |
| + | 2,松本,こんばんは |
| + | 3,中本,"さようなら |
| + | また明日" |
| + | |
| + | 全てのデータを書き出した結果は、 |
| + | |
| + | ID name comment |
| + | 1 山本 こんにちは |
| + | 2 松本 こんばんは |
| + | 3 中本 さようなら |
| + | また明日 |
| + | |
| + | となり、問題なく引用符が消され、改行コードも残っています。 |
| + | |
| + | csvのフォーマットについてはデフォルトではエクセルの書き出しの書式になっているようです。変更可能ですが、ほとんどの場合そのままで良いのでここでは省略します。 |
| | | |
| *CSVファイルの書き込み [#xda09f1c] | | *CSVファイルの書き込み [#xda09f1c] |
| + | |
| + | CSVファイルの書き込みの簡単な例として、さきほどのtest.csvをtest_out.csvというファイルに書き込む方法をあげます。そのコードは以下のようになります。 |
| + | |
| + | inFile = open("test.csv", 'r') |
| + | outFile = open('test_out.csv', 'w') |
| + | |
| + | csvData = csv.reader(inFile) |
| + | |
| + | writer = csv.writer(outFile) |
| + | |
| + | for row in csvData: |
| + | writer.writerow(row) |
| + | |
| + | inFile.close() |
| + | outFile.close() |
| + | |
| + | 上の例ではwriterowというメソッドを使って一行ずつ書きましたが、二次元配列に対応したwriterowsというメソッドもあるので、一気に書き出すこともできます。 |
| + | |
| + | inFile = open("test.csv", 'r') |
| + | |
| + | outFile = open('test_out.csv', 'w') |
| + | |
| + | csvData = csv.reader(inFile) |
| + | |
| + | writer = csv.writer(outFile) |
| + | writer.writerows(csvData) |
| + | |
| + | inFile.close() |
| + | outFile.close() |
| + | |
| + | UTF-8で試してみると予想通りエラーが出ます。 |
| + | |
| + | for row in csvData: |
| + | r1utf = row[1].decode("utf_8") |
| + | writer.writerow((row[0],r1utf,row[2])) |
| + | |
| + | 結果 |
| + | Traceback (most recent call last): |
| + | File "csvTest.py", line 16, in <module> |
| + | writer.writerow((row[0],r1utf,row[2])) |
| + | UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) |
| + | |
| + | 書き込むときはstrに変換するのを忘れないようにしましょう。 |
| + | |
| + | 出力形式はやはりデフォルトではエクセルのCSV書き出しと同じようです。変更も可能ですが、こちらもほとんどの場合そのままで問題ないと思うのでここでは省略します。 |