1.2. csv形式で出力する

#トピック

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

- **DataFrameをcsv形式で出力する方法(エクスポートの方法)**
pandasでcsv形式で出力する

- **日本語を含む場合のオプション** `encoding='shift_jis'`

- **参考ページ**
[https://note.nkmk.me/python-pandas-to-csv/](https://note.nkmk.me/python-pandas-to-csv/)
[https://shilabo.com/python/web_self/a001_000/a001_002/](https://shilabo.com/python/web_self/a001_000/a001_002/)

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ではありません。）

```python
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のエクスプローラーからパスをコピーして、そのままペーストするだけよくなります。

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

或いは

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

とも書けます。

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

```python
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` をオプションで指定します。

```python
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"と名前を付けた場合です。

```python
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の間はアンダースコア(_)でありハイフン(-)ではありません。

```python
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に、更に複雑な日本語の文字を渡すのは賢明ではありません。

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

https://qiita.com/shilabo/items/dcf4630a8f6f83fb9af5

#ポイント整理
- `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/](https://note.nkmk.me/python-pandas-to-csv/)

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

https://shilabo.com/

https://shilabo.com/python/web_self/a001_000/a001_002/