[解決!Python]CSVファイルに書き込みを行うには(pandas編)解決!Python

pandas.DataFrameクラスのto_csvメソッドを使って、データフレームの内容をCSVファイルに書き込む方法を紹介する。

» 2021年09月14日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

import pandas as pd
import numpy as np
from pathlib import Path

data = {
    'name': ['isshiki', 'endo', 'kawasaki'],
    'age': [20, 25, np.nan],
    'weight': [55.44, 66.77, 123.456]
}
df = pd.DataFrame(data)
print(df)
#       name   age   weight
#0   isshiki  20.0   55.440
#1      endo  25.0   66.770
#2  kawasaki   NaN  123.456

# 基本
fname = 'test.csv'
df.to_csv(fname)
print(Path(fname).read_text())
#,name,age,weight
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,,123.456

# 区切り文字の変更
df.to_csv(fname, sep=' ')
print(Path(fname).read_text())
# name age weight
#0 isshiki 20.0 55.44
#1 endo 25.0 66.77
#2 kawasaki  123.456

# 欠損値の表現を指定する
df.to_csv(fname, na_rep='nan')
print(Path(fname).read_text())
#,name,age,weight
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,nan,123.456

# 数値を文字列化する際の書式指定
df.to_csv(fname, float_format='%+08.3f')
print(Path(fname).read_text())
#,name,age,weight
#0,isshiki,+020.000,+055.440
#1,endo,+025.000,+066.770
#2,kawasaki,,+123.456

# ヘッダー行の指定
df.to_csv(fname, header=['col0', 'col1', 'col2'])
print(Path(fname).read_text())
#,col0,col1,col2
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,,123.456

# 行インデックスの列名を指定
df.to_csv(fname, index_label='idx')
print(Path(fname).read_text())
#idx,name,age,weight
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,,123.456

# 行インデックスを出力しない
df.to_csv(fname, index=False)
print(Path(fname).read_text())
#name,age,weight
#isshiki,20.0,55.44
#endo,25.0,66.77
#kawasaki,,123.456

# 書き出す列の指定
df.to_csv(fname, columns=['name', 'weight'])
print(Path(fname).read_text())
#,name,weight
#0,isshiki,55.44
#1,endo,66.77
#2,kawasaki,123.456

# クオートの指定
import csv
df.to_csv(fname, quoting=csv.QUOTE_ALL)
print(Path(fname).read_text())
#"","name","age","weight"
#"0","isshiki","20.0","55.44"
#"1","endo","25.0","66.77"
#"2","kawasaki","","123.456"

df.to_csv(fname, quoting=csv.QUOTE_NONNUMERIC, quotechar="'")
print(Path(fname).read_text())
#'','name','age','weight'
#0,'isshiki',20.0,55.44
#1,'endo',25.0,66.77
#2,'kawasaki','',123.456

# フィールドを囲むのに使う引用符自体がフィールドに含まれている場合の処理
data = {
    "name": ["chak'n", "and pop"],
    "value": [100, 120]
}
df = pd.DataFrame(data)
print(df)
#      name  value
#0   chak'n    100
#1  and pop    120

df.to_csv(fname, quoting=csv.QUOTE_NONNUMERIC, quotechar="'")
print(Path(fname).read_text())
#'','name','value'
#0,'chak''n',100
#1,'and pop',120

df.to_csv(fname, sep=' ', quoting=csv.QUOTE_NONE, escapechar='\\')
print(Path(fname).read_text())
# name value
#0 chak'n 100
#1 and\ pop 120


pandas.DataFrame.to_csvメソッド

 pandasが提供するDataFrameクラスにはto_csvメソッドがあり、これを使うことでデータフレームに格納されているデータをCSVファイルへと書き出せる。

 以下は本稿で紹介するパラメーターを含む、to_csvメソッドの基本的な構文だ。

pandas.DataFrame.to_csv(path, sep, na_rep, float_format, columns, header,
                        index, index_label, quoting, quotechar)


 本稿では以下のパラメーターを紹介する。全てのパラメーターについては、pandasのドキュメント「pandas.DataFrame.to_csv」を参照のこと。

  • path:データフレームの内容を書き出すファイルの名前。必須
  • sep:区切り文字。省略可。省略時はカンマ「,」が指定されたものとして扱われる
  • na_rep:欠損値を表す文字列表現。省略可。省略時は空文字列「""」が指定したものとして扱われる
  • float_format:数値を文字列化してファイルに書き込む際に使われる書式化指定文字列。省略可。省略時は元の値がそのまま文字列化される
  • columns:どの列の値を書き込むかの指定。省略可。省略時は行インデックスに続いて、全ての列が書き込まれる。
  • header:ヘッダー行の指定。True/False、文字列リストを指定可能。文字列リストを指定した場合は、それらがデータフレームの列名の代わりにヘッダー行に使われる。Falseを指定した場合は、ヘッダー行は書き込まれない。Trueを指定した場合は、データフレームの列名がヘッダー行に書き込まれる。省略可。省略時はTrueが指定されたものとして扱われる
  • index:行インデックスを書き込むかどうかを指定する(True/False)。省略可。省略時はTrueが指定されたものとして扱われる(行インデックスが書き込まれる)
  • index_label:行インデックスの列名としてヘッダー行に書き込む値を指定する。headerパラメーターとindexパラメーターがTrueの場合に、index_labelパラメーターに渡した値が行インデックスの列名としてヘッダー行に書き込まれる。省略可。省略時は行インデックスの列名は書き込まれない
  • quoting:CSVファイルに書き込む各フィールドを何らかの引用符で囲むかどうかを指定する。指定可能なのは、Pythonに標準で添付されるcsvモジュールで定義されている定数
  • quotechar:各フィールドを囲む引用符の指定。長さ1の文字。省略可。省略時はダブルクオート「"」が指定されたものとして扱われる

基本的な使い方

 以下では、次のコードで作成したデータフレームをCSVファイルに書き込むものとする。

import pandas as pd
import numpy as np
from pathlib import Path

data = {
    'name': ['isshiki', 'endo', 'kawasaki'],
    'age': [20, 25, np.nan],
    'weight': [55.44, 66.77, 123.456]
}
df = pd.DataFrame(data)
print(df)
#       name   age   weight
#0   isshiki  20.0   55.440
#1      endo  25.0   66.770
#2  kawasaki   NaN  123.456


 一番簡単なのは、書き込むファイル名を指定して、このメソッドを呼び出すだけだ。以下に例を示す。

fname = 'test.csv'
df.to_csv(fname)
print(Path(fname).read_text())
#,name,age,weight
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,,123.456


 出力結果を見ると、ヘッダー行の先頭には行インデックスの列名がない、各行の先頭に行インデックスがある、区切り文字がカンマ「,」となっている、欠損値があれば空文字列が書き込まれることなどが分かるはずだ。

区切り文字の変更

 区切り文字を変更するにはsepパラメーターに長さ1の文字を指定する。以下に例を示す。

df.to_csv(fname, sep=' ')
print(Path(fname).read_text())
# name age weight
#0 isshiki 20.0 55.44
#1 endo 25.0 66.77
#2 kawasaki  123.456


 上の例では「sep=' '」としているので半角空白文字で各フィールドが区切られている。

欠損値の表現を指定する

 欠損値を含むフィールドをCSVファイルに書き込む際に、どんな文字列表現とするかを指定するにはna_repパラメーターにその値を指定する。以下に例を示す。

df.to_csv(fname, na_rep='nan')
print(Path(fname).read_text())
#,name,age,weight
#0,isshiki,20.0,55.44
#1,endo,25.0,66.77
#2,kawasaki,nan,123.456


 この例では、「na_rep='nan'」としているので、CSVファイルの該当するフィールドには「nan」が書き込まれている。

数値を文字列化する際の書式指定

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。