この記事では、Pythonのデータ分析ライブラリのread_csv、to_csv関数で指定できるquotingオプションについてまとめています。
read_csv、to_csvでquotingオプションを指定する目的は、区切り文字やクォーテーション、改行などをエスケープする処理をデフォルトから変更するためです。
また、quotingオプションを指定することでフィールドをfloat型に変換して読み取ることも出来ます。
さっそくですが、指定できる定数と対応する処理を見てみましょう。
定数 | 処理 |
0:csv.QUOTE_MINIMAL | to_csv( ):区切り文字、クォーテーション、改行など特別な文字を含むフィールドのみクォートする |
1:csv.QUOTE_ALL | to_csv(): 全てのフィールドをクォート |
2:csv.QUOTE_NONNUMERIC | to_csv():全ての非数値フィールドをクォート read_csv():クォートされていない全てのフィールドをfloat型に変換 |
3:csv.QUOTE_NONE | to_csv():全てのフィールドをクォートしない。デリミタは設定されているエスケープ文字でエスケープされる。 read_csv():クォート文字を特別扱いしない。 |
なんだか分かりにくいですよね...ということでサンプルで全て試していきます。
今回サンプルにするCSVファイルには以下のようなヘッダーとフィールドを用意しました。
文字列,数値,複合,エスケープ
ABC,123,ABC-123,”ABC,DEF”
サンプルの結果については、入力CSV → DataFrame内部 → 出力CSVという流れで検証していきます。
0:csv.QUOTE_MINIMAL(デフォルト値)
df = pd.read_csv('sample_input.csv')
print(df)
df.to_csv("sample_output.csv", index=False, quoting=0)
実行結果
read_csv() | ABC | 123 | ABC-123 | “ABC,DEF” |
DataFrame | ABC | 123 | ABC-123 | ABC,DEF |
to_csv() | ABC | 123 | ABC-123 | “ABC,DEF” |
0:csv.QUOTE_MINIMALはデフォルト値なので、本来わざわざオプションを書く必要はありません。この場合は、デフォルトで設定してある「quotechar=’”’」に従って「” “」でクォートされた部分は1つのデータとして扱われています。
※もし、quoting=csv.QUOTE_MINIMALで指定する場合は「CSVモジュール」をインポートするのを忘れないようにして下さい。
1:csv.QUOTE_ALL
df = pd.read_csv('sample_input.csv')
print(df)
df.to_csv("sample_output.csv", index=False, quoting=1)
実行結果
read_csv() | ABC | 123 | ABC-123 | “ABC,DEF” |
DataFrame | ABC | 123 | ABC-123 | ABC,DEF |
to_csv() | “ABC” | “123” | “ABC-123” | “ABC,DEF” |
出力したCSVファイルを見てみると、全てのフィールドがクォートされています。
2:csv.QUOTE_NONNUMERIC
df = pd.read_csv('sample_input.csv', quoting=2)
print(df)
df.to_csv("sample_output.csv", index=False, quoting=2)
実行結果
read_csv() | ABC | 123 | ABC-123 | “ABC,DEF” |
DataFrame | ABC | 123.0 | ABC-123 | ABC,DEF |
to_csv() | “ABC” | 123.0 | “ABC-123” | “ABC,DEF” |
どうやらread_csv()でquoting=2を引数にすると数値とみなせるデータはfloat型に変換してDataFrameに格納されるようです。これは便利ですね!
to_csv()に引数に指定すると、出力したCSVにも小数点つきで書き込まれています。
3:csv.QUOTE_NONE
df = pd.read_csv('sample_input.csv', quoting=3)
print(df)
df.to_csv("sample_output.csv", index=False, quoting=3)
このコードを実行するとうまくDataFrameに読み込むことが出来ませんでした。
理由は「” “」がクォーテーションとして認識されなくなった結果、”ABC,DEF”をひとつのデータとして扱うことが出来なくなったからです。
そこで今回は個別に「\」バックスラッシュをエスケープ文字として引数に設定して読込み直してみたいと思います。サンプルのCSVも「\」でエスケープしておきます。
文字列,数値,複合,エスケープ
ABC,123,ABC-123,”ABC\,DEF”
df = pd.read_csv('sample_input.csv', quoting=3, escapechar='\\')
print(df)
df.to_csv("sample_output.csv", index=False, quoting=3, escapechar='\\')
実行結果
read_csv() | ABC | 123 | ABC-123 | “ABC\,DEF” |
DataFrame | ABC | 123 | ABC-123 | “ABC,DEF” |
to_csv() | “ABC” | 123 | “ABC-123” | “ABC\,DEF” |
「\」でエスケープすることが出来ました。これを使えば「”」のみをCSVから読み書きすることも可能です。細かくエスケープを設定する際には重宝しそうです。
以上です。
参考になればうれしいです。
コメント