ExcelやCSVファイルのデータ処理はPandasで。

# はじめに
Pandasは表をDataFrameという形にして、データを分析・整理することのできる、とても便利なPythonライブラリ。エクセル/CSVファイルのデータを整理、整形するのにも役立つ。この記事では、Pandasの基本的な使い方をまとめる。

公式サイトはこちら

https://pandas.pydata.org/

Openpyxlで処理する場合は下記記事へ。

https://qiita.com/tapitapi/items/cdeb7a97ed0add7201b5

# 目次 
+ [Pandas前準備](#pandas前準備)
+ [DataFrame取得 (Excel/CSV→DataFrame)](#dataframe取得)
+ [DataFrame出力 (DataFrame→Excel/CSV)](#dataframe出力)
+ [DataFrameの値処理](#dataframeの値処理)

## Pandas前準備
pandasのライブラリをpipより取得する。pandasでExcelファイルを取り扱う場合は、```openpyxl```と```xlrd```をpandas内で呼び出すため、合わせてpipで取得しておく。
```console:cmd
pip install pandas
pip install openpyxl
pip install xlrd
```
pandasをimportする際、pdに別名設定(エイリアス)して使う。必須ではないが、この記事では以降、pdとして記述する。
```python:pandas_example.py
import pandas as pd
```
[戻る](#目次)


## DataFrame取得
Pandasは、Excel/CSVファイルをDataFrameという型のデータとして取得しデータ処理する。
+ [Excelからデータ取得](#excelからデータ取得)
+ [CSVからデータ取得](#csvからデータ取得)
[戻る](#目次)

### Excelからデータ取得
　Excelからデータ取得する場合、```pd.read_excel```を使う。```pd.read_excel```は、シート名指定取得する方法と、ブックごと取得する方法の2種類ある。
　シート名で取得する場合は、```pd.read_excel```のパラメータ```sheet_name```でシート名を指定する。ブック内のシート一覧は```pd.ExcelFile```で取得できる。
　ブックごと取得する場合は、```sheet_name```でNoneを指定する。ブックごと取得した場合、DataFrame型ではなく、辞書型(dict)になる。シート名をKeyとして指定すれば、DataFrame型として取得できる。**pandas_test.xlsx**を例にすると。下記の通りとなる。

**[pandas_test.xlsx]**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/5cddb737-a619-5a42-82b4-c22dc918f8ec.png)

```python:pandas_example.py
import pandas as pd

#エクセルのシート名取得=============================================
xls_file   = pd.ExcelFile('pandas_test.xlsx')
xls_sheets = xls_file.sheet_names
print(xls_sheets)
# ['example_1', 'example_2']

#シート指定読み出し=================================================
for sheet in xls_sheets:
	df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = sheet)
	print(type(df_sheet))
	print(df_sheet)
# <class 'pandas.core.frame.DataFrame'>
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# ....
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10
# <class 'pandas.core.frame.DataFrame'>
#            果物  個数
# 0       apple  10
# 1      orange  90
# 2      banana  80
# ....
# 8      cherry  20
# 9        kiwi  10

#全シート同時読み出し===============================================
df_book = pd.read_excel('pandas_test.xlsx',sheet_name = None)
print(type(df_book))
# <class 'dict'>

#シート名をKeyで指定して読み出し====================================
for key in df_book.keys():
	df_sheet = df_book[key]
	print(type(df_sheet))
	print(df_sheet)
# <class 'pandas.core.frame.DataFrame'>
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# ....
# 8       i    け   90  0.09
# 9       j    こ  100  0.10
# <class 'pandas.core.frame.DataFrame'>
#            果物  個数
# 0       apple  10
# 1      orange  90
# 2      banana  80
# ....
# 8      cherry  20
# 9        kiwi  10
```
#### 列名・行名 (header/index_col/names)
表のデータから行名、列名を使うか使わないかは、```header(列名)```と```index_col(行名)```で指定できる。

列名|行名|-
-------------|----------------|-
header = 0   |index_col = None|列名を0行目データからとる。(Default)
header = None|index_col = None|データから名称を使わない。
header = None|index_col = 0   |行名を0列目データからとる。
header = 0   |index_col = 0   |列名を0行目データ、行名を0列目データからとる。

また、列名を新たに付与したい場合は、```names```で付与できる。ただし、```names```を使う場合は、```header```との組み合わせに注意すること。```header=0```で、```names```を使うと、元データの0行目がなくなる。

```python:pandas_example.py
# header=0,index_col=None(default)
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', header=0,index_col=None)
print(df_sheet)
#            果物  個数
# 0       apple  10
# 1      orange  90
# 2      banana  80

# header=None,index_col=None
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', header=None,index_col=None)
print(df_sheet)
#              0   1
# 0           果物  個数
# 1        apple  10
# 2       orange  90

# header=None,index_col=0
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', header=None,index_col=0)
print(df_sheet)
#             1
# 0
# 果物          個数
# apple       10
# orange      90

# header=0,index_col=0
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', header=0,index_col=0)
print(df_sheet)
#             個数
# 果物
# apple       10
# orange      90

# header=0,index_col=None + names[]
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', names=['A','B'] ,header=0,index_col=None)
print(df_sheet)
#             A   B
# 0       apple  10
# 1      orange  90
# 2      banana  80
# 3       peach  70

# header=None,index_col=None + names[]
df_sheet = pd.read_excel('pandas_test.xlsx', sheet_name = 'example_2', names=['A','B'] ,header=None,index_col=None)
print(df_sheet)
#              A   B
# 0           果物  個数
# 1        apple  10
# 2       orange  90
# 3       banana  80
```
[戻る](#dataframe取得)



### CSVからデータ取得
　CSVからデータ取得する場合、```pd.read_csv```を使う。```header/index_col/names```の考え方はExcelと同じ。CSVファイルがShift-jisだった場合は、```encoding='cp932'```でエンコード必要。**pandas_test.csv**を例にすると。下記の通りとなる。

**[pandas_test.csv]**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/81b967a7-363b-0149-32b7-aaae8e8afd52.png)


```python:pandas_example.py
df = pd.read_csv('pandas_test.csv',encoding='cp932')
print(df)
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# 3       d    え   40  0.04
# 4       e    お   50  0.05
# 5       f    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10
```
[戻る](#dataframe取得)


## DataFrame出力
DataFrameをExcelやCSVへ出力する。
+ [Excelへデータ出力](#excelへデータ出力)
+ [CSVへデータ出力](#csvへデータ出力)
[戻る](#目次)

### Excelへデータ出力
　DataFrameからExcelへデータ出力する場合、```df.to_excel```を使う。上書きでエクセルファイルへ出力したい場合は、```ExcelWriter```とセットで使う。

 パラメータ|意味
---|---
sheet_name|出力先のシート名
encoding|文字エンコード
header|DataFrameのヘッダ(列名)を出力するかどうか(True/False)。<br>headerにリストを指定すると、そのリストがヘッダになる。
index|DataFrameのインデックス(行名)を出力するかどうか(True/False)。
columns|出力列を指定。なにも指定しない場合はすべての列を出力。

```python:pandas_example.py
# 下記DataFrameをエクエルへ出力
df = pd.read_csv('pandas_test.csv',encoding='cp932')
print(df)
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# 3       d    え   40  0.04
# 4       e    お   50  0.05
# 5       f    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10

# Excelへ出力(シート名1)
df.to_excel('out_excel.xlsx',sheet_name='シート名1',encoding='cp932',header=True,index=True)

# ヘッダ・インデックスなし(シート名2)
with pd.ExcelWriter('out_excel.xlsx', mode='a') as f:
    df.to_excel(f,sheet_name='シート名2',encoding='cp932',header=False,index=False)

# ヘッダ名変更(シート名3)
header_list=['1列目','2列目','3列目','4列目']

with pd.ExcelWriter('out_excel.xlsx', mode='a') as f:
    df.to_excel(f,sheet_name='シート名3',encoding='cp932',header=header_list,index=False,)
    
# アルファベットとひらがなだけ(シート名4)
with pd.ExcelWriter('out_excel.xlsx', mode='a') as f:
    df.to_excel(f,sheet_name='シート名4',encoding='cp932',header=True,index=False,columns=['アルファベット','ひらがな']) 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/46617d35-e2d1-c01a-4104-e2f9de9c2a27.png)

[戻る](#dataframe出力)

### CSVへデータ出力
　DataFrameからCSVへデータ出力する場合、```df.to_csv```を使う。各種パラメータは```df.to_excel```と同じ。ただし、CSVはシートの概念がないので、```sheet_name```は使えない。
```python:pandas_example.py
# 下記DataFrameをCSVへ出力
df = pd.read_csv('pandas_test.csv',encoding='cp932')
print(df)
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# 3       d    え   40  0.04
# 4       e    お   50  0.05
# 5       f    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10

# CSVへ出力
df.to_csv("out_csv.csv",encoding='cp932',header=True,index=True)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/7f84f98a-26c3-6882-9b0f-3d8130b0821f.png)


[戻る](#dataframe出力)

## DataFrameの値処理
DataFrameの行・列・セルの指定と、値の読み書き方法についてまとめる。

パラメータ|意味
---|---
df[列名]|列すべての値を得る
df.loc[行範囲 , 列範囲]|行列の範囲を指定してい値を得る。<br>列範囲は省略すると、すべての列が指定される。<br>複数行、複数列を指定したい場合はリストで指定する。<br>スライスを使って範囲を指定することもできる。
df.at[行,列]|セルを指定する。
df.iloc[行範囲 , 列範囲]|列範囲をヘッダ名でなく数値で指定する。あえてilocを使う用途が思い浮かばない。
df.iat[行 , 列]|列をヘッダ名でなく数値で指定する。ilocと同じくあえてiatを使う用途が思い浮かばない。

```python:pandas_example.py
# 下記DataFrameを処理する
df = pd.read_csv('pandas_test.csv',encoding='cp932')
print(df)
#   アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    い   20  0.02
# 2       c    う   30  0.03
# 3       d    え   40  0.04
# 4       e    お   50  0.05
# 5       f    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10

# df[列名]====================================
# 列指定 'ひらがな'列すべて
print(f'{df["ひらがな"]=}')

# df["ひらがな"]=
# 0    あ
# 1    い
# 2    う
# 3    え
# 4    お
# 5    か
# 6    き
# 7    く
# 8    け
# 9    こ


# df.loc[行範囲 , 列範囲]=====================
#---------------------------------------------
# loc行指定：0行目
#---------------------------------------------
print(f'{df.loc[0]=}')

# df.loc[0]=
# アルファベット       a
# ひらがな          あ
# 整数           10
# 小数         0.01

#---------------------------------------------
# loc行指定：0～5行目
#---------------------------------------------
print(f'{df.loc[0:5]=}')

# df.loc[0:5]=
# アルファベット ひらがな  整数    小数
# 0       a    あ  10  0.01
# 1       b    い  20  0.02
# 2       c    う  30  0.03
# 3       d    え  40  0.04
# 4       e    お  50  0.05
# 5       f    か  60  0.06

#---------------------------------------------
# loc行指定：1,3行目 ※[]で括ってリストで指定
#---------------------------------------------
print(f'{df.loc[[1,3]]=}')

# df.iloc[[1,3]]=
# アルファベット ひらがな  整数    小数
# 1       b    い  20  0.02
# 3       d    え  40  0.04

#---------------------------------------------
# loc行列指定：0～5行目 "ひらがな"列指定
#---------------------------------------------
print(f'{df.loc[0:5,"ひらがな"]=}')
# df.loc[0:5,"ひらがな"]=
# 0    あ
# 1    い
# 2    う
# 3    え
# 4    お
# 5    か

#---------------------------------------------
# loc行列指定：0～5行目 "ひらがな"～"小数"列目指定
#---------------------------------------------
print(f'{df.loc[0:5,"ひらがな":"小数"]=}')
# df.loc[0:5,"ひらがな":"小数"]=
# ひらがな  整数    小数
# 0    あ  10  0.01
# 1    い  20  0.02
# 2    う  30  0.03
# 3    え  40  0.04
# 4    お  50  0.05
# 5    か  60  0.06

#---------------------------------------------
# loc行列指定：1,3行目 "ひらがな","整数"列目指定
#---------------------------------------------
print(f'{df.loc[[1,3],["ひらがな","整数"]]=}')
# df.loc[[1,3],["ひらがな","整数"]]=
# ひらがな  整数
# 1    い  20
# 3    え  40

#---------------------------------------------
# 値変更
#---------------------------------------------
df.loc[[1,3],["ひらがな","整数"]]= '〇'
print(f'{df=}')

# df=  アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    〇    〇  0.02
# 2       c    う   30  0.03
# 3       d    〇    〇  0.04
# 4       e    お   50  0.05
# 5       f    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10



# df.at[行 , 列]==============================
#---------------------------------------------
# atセル指定：5行,アルファベット列
#---------------------------------------------
print(f'{df.at[5,"アルファベット"]=}')
# df.at[5,"アルファベット"]='f'

#---------------------------------------------
# 値変更
#---------------------------------------------
df.at[5,"アルファベット"]='×'
print(f'{df=}')

# df=  アルファベット ひらがな   整数    小数
# 0       a    あ   10  0.01
# 1       b    〇    〇  0.02
# 2       c    う   30  0.03
# 3       d    〇    〇  0.04
# 4       e    お   50  0.05
# 5       ×    か   60  0.06
# 6       g    き   70  0.07
# 7       h    く   80  0.08
# 8       i    け   90  0.09
# 9       j    こ  100  0.10
```
[戻る](#目次)

以上