Pandasはファイルの入出力に関する関数が豊富で、機能も多いです。
その中でも、CSVファイルで書き出すことでエクセルや他のアプリケーションでも読み込める場合が多いことから、CSVで書き出したいことは多いはずです。本記事で紹介するto_csv
関数は名前の通り、CSV形式のファイルを出力してくれる便利な関数です。
-
to_csv
関数の簡単な使い方
について使いこなせるように解説します。
csv形式のファイルを読み込む関数であるread_csv
関数の解説は以下の記事でしています。
Pandasのread_csv関数でCSVファイルを読み込む方法 /features/pandas-readcsv-light.html
to_csv
id,age,name,math,english,birth
012,21,Amanda,78,25,1996/9/21
014,22,Bob,65,67,1995/10/31
019,21,Charlotte,98,87,1997/4/24
033,23,David,35,40.1995/5/1
051,22,Emily,69,72,1996/6/4
081,21,Fred,95,90,1997/7/10
090,22,Gary,23,25,1995/12/21
このcsvファイルのデータを例に考えてみます。
このファイルは以下のリンクをクリックすればダウンロードできます。 sample_tocsv.csv
Pythonのインタラクティブシェルを起動して、このファイルを読み込みます。
index_col
でインデックスにする列(カラム)を指定し、parse_dates
でTimeStamp型で読み込む列(カラム)を指定しています。
In [1]:import pandas as pd
In [6]: df = pd.read_csv("sample_tocsv.csv", index_col=0, parse_dates=['birth'])
In [7]: df
Out[7]:
age name math english birth
id
12 21 Amanda 78 25 1996-09-21
14 22 Bob 65 67 1995-10-31
19 21 Charlotte 98 87 1997-04-24
33 23 David 35 40 1995-05-01
51 22 Emily 69 72 1996-06-04
81 21 Fred 95 90 1997-07-10
90 22 Gary 23 25 1995-12-21
基本的な操作
まずは特に何もせずそのまま保存してみます。(DataFrame).to_csv(<保存先のpath>)
で保存できます。
s1.csv
の名前で保存してみましょう。
ちなみにipythonでは!cat
のように!
をつけてコマンドを実行するとコマンドシェルでの操作を行なってくれます。
In [9]: df.to_csv("s1.csv")
In [10]: !cat s1.csv
id,age,name,math,english,birth
12,21,Amanda,78,25,1996-09-21
14,22,Bob,65,67,1995-10-31
19,21,Charlotte,98,87,1997-04-24
33,23,David,35,40,1995-05-01
51,22,Emily,69,72,1996-06-04
81,21,Fred,95,90,1997-07-10
90,22,Gary,23,25,1995-12-21
うまく保存できていますね。
headerの有無の指定 header
今度はheader
をなくして保存してみます。引数header=False
にすればうまく保存されたcsvファイルにヘッダーが書き込まれません。
In [11]: df.to_csv("s2.csv", header=False)
In [12]: !cat s2.csv
12,21,Amanda,78,25,1996-09-21
14,22,Bob,65,67,1995-10-31
19,21,Charlotte,98,87,1997-04-24
33,23,David,35,40,1995-05-01
51,22,Emily,69,72,1996-06-04
81,21,Fred,95,90,1997-07-10
90,22,Gary,23,25,1995-12-21
indexの有無の指定 index
index=False
にすればインデックスが書き込まれません。
In [13]: df.to_csv("s3.csv", index=False)
In [14]: !cat s3.csv
age,name,math,english,birth
21,Amanda,78,25,1996-09-21
22,Bob,65,67,1995-10-31
21,Charlotte,98,87,1997-04-24
23,David,35,40,1995-05-01
22,Emily,69,72,1996-06-04
21,Fred,95,90,1997-07-10
22,Gary,23,25,1995-12-21
インデックスが連番であってもデフォルトだとcsvファイルに書き込まれてしまうのでindex=False
でそれを防ぎます。
In [15]: df_2 = df.reset_index() # インデックスに指定されたデータを列(カラム)に戻す
In [16]: df_2
Out[16]:
id age name math english birth
0 12 21 Amanda 78 25 1996-09-21
1 14 22 Bob 65 67 1995-10-31
2 19 21 Charlotte 98 87 1997-04-24
3 33 23 David 35 40 1995-05-01
4 51 22 Emily 69 72 1996-06-04
5 81 21 Fred 95 90 1997-07-10
6 90 22 Gary 23 25 1995-12-21
In [17]: df_2.to_csv("s5.csv", index=False)
In [18]: !cat s5.csv
id,age,name,math,english,birth
12,21,Amanda,78,25,1996-09-21
14,22,Bob,65,67,1995-10-31
19,21,Charlotte,98,87,1997-04-24
33,23,David,35,40,1995-05-01
51,22,Emily,69,72,1996-06-04
81,21,Fred,95,90,1997-07-10
90,22,Gary,23,25,1995-12-21
特定の列(カラム)だけを保存する columns
columns=<使用したいカラムのリスト>
とすれば特定のカラムだけ保存することが可能です。
In [19]: df.to_csv("s6.csv", columns=["name","math"])
In [20]: !cat s6.csv
id,name,math
12,Amanda,78
14,Bob,65
19,Charlotte,98
33,David,35
51,Emily,69
81,Fred,95
90,Gary,23
読み込みモードの指定 mode
デフォルトでmode="w"
になっており、同じ名前のファイルがあったとしても内容が上書きされることになっています。
上書きせず、データをそのまま付け足す形で使いたいときはmode="a"
にすれば上書きではなく書き足すことが可能です。
In [32]: data = {
"id": [ 88, 110],
"age": [22, 21],
"name":["Cathy", "Ronald"],
"math":[80,81],
"english":[34,87],
"birth":[pd.Timestamp(1995,8,25),pd.Timestamp(1996,9,4)]
}
In [48]: df_ad = pd.DataFrame(data, columns=["age","name","math","english","birth", "id"])
In [51]: df_ad.set_index("id", inplace=True) # インデックスに"id"を設定
In [53]: df_ad.to_csv("s1.csv", mode="a", header=False) # s1.csvに書き足す
In [54]: !cat s1.csv
id,age,name,math,english,birth
12,21,Amanda,78.0,25,1996-09-21
14,22,Bob,65.0,67,1995-10-31
19,21,Charlotte,98.0,87,1997-04-24
33,23,David,35.0,40,1995-05-01
51,22,Emily,69.0,72,1996-06-04
81,21,Fred,95.0,90,1997-07-10
90,22,Gary,23.0,25,1995-12-21
88,22,Cathy,80,34,1995-08-25
110,21,Ronald,81,87,1996-09-04
きちんと追記できていますね。header=False
にしないと間にヘッダーが書き込まれることになりますので注意が必要です。
大量のデータを扱うときなどはこうやって逐一ファイルに保存できるようになるとメモリを圧迫せずにすむのでこの使い方は覚えておくと便利だと思います。
read_csv
関数のchunksize
引数との相性が良いです。
Using Chunksize in Pandas – Another Dev Notes
上記のサイトでその例を示しています(英語ですが比較的読みやすいです)。100億以上ものデータセットを受け取ってメモリーに入りきらなかったのでread_csv
関数のchunksize
を使って小さくした塊ごとに処理を行ったというものです。
ここでも注記でto_csv
関数の引数mode
は"a"
にしておきましょうと書いてあります。
区切り文字の変更 sep
sep
引数で区切り文字を変更できます。;
で区切ってみましょう。
In [55]: df.to_csv("s7.csv", sep=";")
In [56]: !cat s7.csv
id;age;name;math;english;birth
12;21;Amanda;78.0;25;1996-09-21
14;22;Bob;65.0;67;1995-10-31
19;21;Charlotte;98.0;87;1997-04-24
33;23;David;35.0;40;1995-05-01
51;22;Emily;69.0;72;1996-06-04
81;21;Fred;95.0;90;1997-07-10
90;22;Gary;23.0;25;1995-12-21
アウトプット先をsys.stdoutに変更
データをファイルに保存するのではなく標準出力に出力させることもできます。先ほどまでファイル保存先のpathをしていた箇所にsys.stdout
を指定してやるとデータの中身が標準出力されます。
以下のコードをto_csv_stdout.py
の名前で保存してください。
import pandas as pd
import sys
df = pd.read_csv("sample_tocsv.csv", index_col=0, parse_dates=['birth'])
df.to_csv(sys.stdout)
これをコマンドライン上で
$ python to_csv_stdout.py
で実行するとファイルの中身が表示されるはずです。
Pandasのバージョン(0.23.1)では表示されないバグが混入しているので注意してください。
成功すると、以下のようにコンソールに出力されます。
id,age,name,math,english,birth
12,21,Amanda,78,25,1996-09-21
14,22,Bob,65,67,1995-10-31
19,21,Charlotte,98,87,1997-04-24
33,23,David,35,40,1995-05-01
51,22,Emily,69,72,1996-06-04
81,21,Fred,95,90,1997-07-10
90,22,Gary,23,25,1995-12-21
うまく表示されました。
まとめ
今回はPandasのto_csv
関数の使い方についてまとめました。
全ての引数について解説したわけではありませんが、これで一通り扱えるようになるはずです。元のファイルから読み込む場合と違って、ファイル出力するときは形式に特にこだわらない限り(DataFrame または Series).to_csv(<出力するファイル名>)
とシンプルに記述することが可能です。
Pythonの標準モジュールを使ってファイルを書き込むこともできますが、Pandasを使っているならこの関数が非常に簡単で便利でしょう。
参考
- Python for Data Analysis 2nd edition –Wes McKinney(書籍)
- pandas.DataFrame.to_csv — pandas 0.23.3 documentation