Data Frame編集@ Pandas

#DataFrame
データフレーム(Data Frame)はpandasの主要なデータ構造である[1]．行(index)と列(columns)にそれぞれ名前を付けた表のように扱うことができる．
DataFrame(data)でdataをこのデータ構造(表形式データ)に変換できる．
dataの中身は，np.arrayでもDictionary(辞書配列)でもよい．辞書配列の場合，columnにすでにインデックスが振られた状態となる．
DataFrameにおいてindex,columnsを指定するときにはカッコとして[ ]が使われる．


```py
import pandas as pd
import numpy as np

d1 = np.array([[1,2,3],[3,2,2]])
data1 = pd.DataFrame(d1)
#何も名前を付けないと勝手にindexとcolumnに[0,1,2..]と数字が振られる

data2 = pd.DataFrame(d1,index = ['a','b'])
#indexにa,bという名前を振った
#出力は以下の通り
'''
   0  1  2
a  1  3  2
b  2  3  1
'''

d2 = {"a":[1,2,3],"b":[2,2,1]}
#Dictionaryで入力
data3 = pd.DataFrame(d2)
#元のデータに名前があると，自動でColumnに名前"a","b"がついた
```

data3は以下の様になる．

| Index  |  a  |  b  |  
|:--:|:--:|:--:|
|0|1|2|
|1|2|2|
|2|3|1|

#要素追加，編集
手軽な方法は，ないindex,columns名を指定することだと思う．concatを使う方法もある．

```python

import pandas as pd
df1 = pd.DataFrame([[1,3,2],[2,3,1]],columns= ['a','b','c'])
#    a  b  c
# 0  1  3  2
# 1  2  3  1

##行追加，編集
df1['d'] = 0
#    a  b  c  d
# 0  1  3  2  0
# 1  2  3  1  0

##列追加
df.loc[2] = [3,1,1,2]
#    a  b  c  d
# 0  1  3  2  0
# 1  2  3  1  0
# 3  3  1  1  2

```

#抽出，削除
locを使うと便利．

```py

import pandas as pd
import numpy as np

d1 = np.array([[1,2],[3,2],[2,0]])
df3 = pd.DataFrame(d1,columns = ['a','b'])
#    a  b
# 0  1  2
# 1  3  2
# 2  2  0

##抽出##
#行・列の特定による抽出(0-2行目、a列の抽出)
df4 = df3.loc[0:2,'a']
#    a
# 0  1
# 1  3
# 2  2

#セルの中身一致となる行抽出1(a == 3となる行)
df4 = df3.query('a == 3')
#セルの中身一致となる行抽出2
df4 = df3[ df3['a'] == 3 ]
#いずれの場合も結果は以下の通り
#    a  b
# 1  3  2

#bの列削除(行でも同じことができる)
df4 = df3.drop(['b'],axis=1)
#    a
# 0  1
# 1  3
# 2  2

#要素追加
data3["c"]=[4,3,1]

#データ出力
data3.to_csv('out.csv',header=True)
```

#その他結合方法
①pd.concatを使うとデータフレーム同士を結合できる．
②DataFrame.appendを用いる用いる

```py

import pandas as pd

df1 = pd.DataFrame([[1,3,2],[2,3,1]],columns= ['a','b','c'])
#    a  b  c
# 0  1  3  2
# 1  2  3  1

df2 = pd.DataFrame([[2,2,2]],columns = ['a','b','c'])

##行方向結合①
df2 = pd.concat([df1,df2])
#行方向結合②
df2 = df1.append(df2)
#どちらも結果は以下の通り
#    a  b  c
# 0  1  3  2
# 1  2  3  1
# 0  2  2  2



##列方向結合 (axis = 1 で指定する)
df2 = pd.concat([df1,df2],axis = 1, keys = ['x','y'])
#keysで，データの塊ごとに名前を付けられる
#    x          y          
#    a  b  c    a    b    c
# 0  1  3  2  2.0  2.0  2.0
# 1  2  3  1  NaN  NaN  NaN
```

#実際にcsvデータ読込で練習してみる
[気象庁の気象データ](https://www.data.jma.go.jp/gmd/risk/obsdl/index.php)から神戸市の7月の日最高気温データをダウンロードした．csvファイルの概要は以下の通りである．

```
ダウンロードした時刻：2018/07/27

,神戸,神戸,神戸
年月,日最高気温の平均(℃),日最高気温の平均(℃),日最高気温の平均(℃)
,,品質情報,均質番号
1969/7,28.8,8,1
1970/7,29.8,8,1
1971/7,30.0,8,1
1972/7,29.5,8,1
...
```

このデータを読み取るときに二つ課題が生じる．
1. 日本語の読取
2. 最初の行(ダウンロードした時刻)がData Frameの構造を壊す(n行1列になってしまう)
以下の様にすると二つの課題を解決できた．

```py
import pandas as pd
data = pd.read_csv('data.csv',\
#読み込むファイル名
                   encoding="SHIFT-JIS",\
#日本語で読み取るため，コーディング変更[2]
                   sep = ",",\
#何でセパレートするか(csvでは",")
                   skiprows = 3)              #最初の3行を読み取らない
data = pd.read_excel('example.xlsx')
#ちなみにxlsxファイルはこれで読取
data.to_csv('data_modified.#データ出力
```

##DataFrame編集
データ読込時点はこのような構造になっている．

|       年月 | 日最高気温の平均(℃) | 日最高気温の平均(℃) | 日最高気温の平均(℃)|
|:--:|:--:|:--:|:--:|
|0  |    NaN   |       NaN  |        品質情報     |     均質番号|
|1  | 1969/7  |      28.8  |           8        |     1  |
|...|...|...|...|

```py
import pandas as pd

data = pd.read_csv('data.csv',\
                   encoding="SHIFT-JIS",\
                   sep = ",",skiprows = 3)

col = ["Date","Max_temp","Data_Qlt","Data_Sim"];
data.columns = col                                      #Column名変更
data1 = data.rename(index={0:'a'})                      #index名一部変更(reindexでも可)
```

|       Date | Max_Temp | Data_Qlt | Data_Sim |
|:--:|:--:|:--:|:--:|
|a  |    NaN   |       NaN  |        品質情報     |     均質番号|
|1  | 1969/7  |      28.8  |           8        |     1  |
|...|...|...|...|


```py
data1 = data1.drop(['a'])                               #'a'行を削除
data1 = data1.drop(['Data_Qlt'],axis = 1)               #'Data_Qlt'列を削除
```
|       Date | Max_Temp | Data_Sim |
|:--:|:--:|:--:|:--:|
|1  | 1969/7  |      28.8        |     1  |
|...|...|...|

```py
data_2007 = data1[data1['Date']=='2007/7']　　　　　　　 #Dateが2007の列を取得
```

Data_2007の結果は以下の様になる

| index | Date | Max_temp | Data_Sim |
|:-----:|:----:|:--------:|:--------:|
|39     |2007/7|28.5      |2         | 










**参照**
[1] [Pandas 0.23 documentation](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html#pandas.DataFrame)
[2] [日本語のcsvファイル読み込み](http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/python/encoding.html)
[3][Pandas 0.23 documentation](https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html)