0
0

More than 1 year has passed since last update.

1.2. csv形式で出力する

Posted at

トピック

DataFrameをcsv形式で出力(エクスポート)する方法を説明します。

DataFrameを操作し、意図通りにできたか確認する為、csvで出力して確認することが非常に多いです。
なので、Pythonの学習を進める際に、先に出力の方法を知っておくと効率的です。

尚、numpy の ndarray は、この方法では出力できません。

ですから、自分が今、何を扱っているのかを意識する事がとても重要です。
ここでは、「DataFrameを扱っており、List、Series、arrayではない」という事です。

参考HP:List, Series, DataFrameの違いを正確に理解する
https://shilabo.com/python/web_self/a002_000/a002_001/

pandasでcsv形式で出力する

pandasのdf.to_csv() を使います。

ここでは、例として以下の DataFrame のdf1aをcsvに出力します。
(注意:indexをindex=[11,12,13]で指定しています。ですので、indexは0,1,2ではありません。)

import pandas as pd
df1a = pd.DataFrame([[1863,7911,2634],[1850,8000,2623],[1853,7980,2578]], index=[11,12,13], columns=['clm1','clm2','clm3'])
print('--- df1a ---\n', df1a)
#-- df1a ---
#     clm1  clm2  clm3
#11  1863  7911  2634
#12  1850  8000  2623
#13  1853  7980  2578

df.to_csv('ファイル名') で出力できます。
但し、日本語を含む場合、後述するオプションが必要です。

ファイルのパスは、例えば、Windowsのドキュメントに保存したい場合、

C:\Users\ユーザ名\Documents

となります。以下はユーザー名が shilabo の場合です。
パスを指定する場合rと頭に書くと、\(バックスラッシュ=¥マーク が1個)を\\(バックスラッシュ=¥マークが2個)と書く必要がなくなり便利です。

つまりrと書けば、バックスラッシュ(¥マーク)は1つですみます。
Windowsのエクスプローラーからパスをコピーして、そのままペーストするだけよくなります。

df1a.to_csv(r'C:\Users\shilabo\Documents\df1a.csv') #既に import pandas as pd を書いている前提

或いは

f = r'C:\Users\shilabo\Documents\df1a.csv'
df1a.to_csv(f)

とも書けます。

ヘッダーが不要な場合、header=Falseをオプションで指定します。

df1a.to_csv(r'C:\Users\shilabo\Documents\df1b.csv', header=False)

#このようなデータが出力されます。'clm1','clm2','clm3'がありません。
#11  1863  7911  2634
#12  1850  8000  2623
#13  1853  7980  2578

indexも不要な場合、index=False をオプションで指定します。

df1a.to_csv(r'C:\Users\shilabo\Documents\df1c.csv', header=False, index=False)

#このようなデータが出力されます。'clm1','clm2','clm3'も 11,12,13 もありません。
#1863  7911  2634
#1850  8000  2623
#1853  7980  2578

出力したcsvのindexの先頭に"日付"や"管理番号"のような名前(カラム名のようなもの)を付けたい場合があります。これは、 index_label=で指定できます。
以下は、"ID"と名前を付けた場合です。

df1a.to_csv(r'C:\Users\shilabo\Documents\df1a_idx.csv', index_label='ID')
#'C:\Users\shilabo\Documents\df1a_idx.csv'として出力
#このようなファイルが出力されます。IDと書いてあります。
#ID  clm1  clm2  clm3
#11  1863  7911  2634
#12  1850  8000  2623
#13  1853  7980  2578

日本語を含む場合

日本語を含む場合は、オプションencoding='shift_jis' を指定しなければいけません。
指定しないと、文字化けします。Pythonは日本語が苦手です。

以下の例では、カラム名(列名)に日本語を含むので、encoding='shift_jis'を指定します。
shiftとjisの間はアンダースコア(_)でありハイフン(-)ではありません。

df2a = pd.DataFrame([[1863,7911,2634],[1850,8000,2623],[1853,7980,2578]], index=[11,12,13], columns=['銘柄1','銘柄2','銘柄3'])
print('--- df2a ---\n',df2a)
#--- df2a ---
#     銘柄1   銘柄2   銘柄3
#11  1863  7911  2634
#12  1850  8000  2623
#13  1853  7980  2578

# 日本語はencoding='shift_jis'が必要
df2a.to_csv(r'C:\Users\shilabo\Documents\df2a.csv',encoding='shift_jis') 

しかし、日本語だからshift_jisを指定してもエラーとなる場合があります。以下のようなエラーのはずです。

UnicodeEncodeError: 'shift_jis' codec can't encode character '\u2460' in position 2: illegal multibyte sequence

原因は、①、②、③やⅠ、Ⅱ、Ⅲ(1,2,3とタイプして全角変換)という文字です。

この場合encoding='cp932'を指定すれば解決できます。しかし、このような文字は使わないようにましょう。

なぜならば、そのような文字を含んだファイルを誰かが読み込む時、encodingに原因があると気付かない場合があり、時間の浪費になります。
また、encoding='cp932'を知っている人は少なく、トラブルの原因になるからです。

ですので、書き出す場合だけでなく、読み込む際であっても、そのような文字は削除することを勧めています。
日本語が苦手なPythonに、更に複雑な日本語の文字を渡すのは賢明ではありません。

このような文字については、以下のページも参照してください。

ポイント整理

  • pd.to_csv()を使う。
  • 日本語を含む場合、encoding='shift_jis'をオプションに指定する。
  • ①やⅠ(1とタイプして全角変換)があれば、encoding='cp932'で解決できる。しかし、このような文字は使うべきでない。(取り除くべき)
  • header = False / Trueでヘッダーの有無を指定できる。
  • index = False / Trueでindexの有無を指定できる。
  • index_label='名前'でindexのヘッダーを指定できる。

参考ページ

  • もっと詳しく知りたい場合、以下のサイトが非常に役に立ちます。
    https://note.nkmk.me/python-pandas-to-csv/

  • 以下のページでは実践で使っている技術が掲載されています。書籍のように構成されています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0