「Python Pandas もくもく勉強会 in 新潟 #2」まとめ


# 1. Python Pandas もくもく勉強会 in 新潟 #2

2019/08/04 に「Python Pandas もくもく勉強会 in 新潟 #2」を開催しました。本記事は、その時に行われた質問やアドバイス等を、勉強会後に、自分なりにまとめたものです。Pandas の理解を深める一助となれば幸いです。内容について間違いや問題等ありましたらご連絡お願いします。

(参考1) 本勉強会の開催案内 → https://connpass.com/event/139933/
(参考2) 次回勉強会の開催案内  → https://connpass.com/event/142121/

## 1.1. pandas では string(文字列) は dtype='object' になる

```python
   data = ['a']
   pd.Series(data)
   data.dtype
   # 0    a
   # dtype: object
```

## 1.2. Series で s[index] としたとき戻り値が Series になるときとならない時がある

Series に重複する index がある場合は、 s[index] とすると Series が戻る。

```python
data = [1, 2, 3]
s = pd.Series(data, index=['a', 'b', 'a'])
s
# a    1
# b    2
# a    3
# dtype: int64

s['a']
# a    1
# a    3
# dtype: int64
```
しかし、 index に重複がない場合 Series ではなく値が戻る。

```python
s['b']
# 2
```

Series で s[['b']] のようにすれば、値ではなく必ず Series として戻るので、 index に重複があってもなくても常に Series で戻るので処理を統一できて便利。

```python
s[['b']]
# b    2
# dtype: int64
```

## 1.3. ディクショナリで渡す時は、順序を保持したい場合は OrderedDict を使用すれば良い?

勉強会後に調べたところ、 pd.DataFrame.from_dict 関数に OrderedDict を渡せば良いことがわかりました。
pd.concat を使用してもできます。アドバンスドな内容なため深入りはしません。
https://stackoverflow.com/questions/13653030/how-do-i-pass-a-list-of-series-to-a-pandas-dataframe

## 1.4. DataFrame を辞書で作成する場合、辞書のそれぞれのバリューのリストの長さは同じでなければならない。そうでなければエラーとなる

```python
data1 = [1, 2, 3]
data2 = [10, 20]
df = pd.DataFrame({'A': data1, 'B': data2})
# ValueError: arrays must all be same length
```

## 1.5. DataFrame を Series の辞書で作成する場合、辞書のバリューの Series の長さは異なってもエラーにはならない。Series のマージが行われ、カラムで元の Series に存在しないindex の値には欠損値が設定される

```python
data1 = ['10', '20', '30']
data2 = ['100', '300']
s1 = pd.Series(data1, index=[1, 2, 3])
s2 = pd.Series(data2, index=[1, 3])
df = pd.DataFrame({'A': s1, 'B':s2})
df
#     A    B
# 1  10  100
# 2  20  NaN
# 3  30  300
```

## 1.6. name 属性 は何に使われる?
勉強会後に調べたところ、 一つの Series を DataFrame に変換すると name 属性がカラム名として登録されるようです。
(参考URL) https://stackoverflow.com/questions/13653030/how-do-i-pass-a-list-of-series-to-a-pandas-dataframe

```python
data = ['a', 'b', 'c']
s = pd.Series(data, name='Apple')
df = pd.DataFrame(s)
df.columns
# Index(['Apple'], dtype='object')
```

ただし、 二つの Series をリストとして渡すと以下のようになってしまいます.

```python
data1 = ['a', 'b', 'c']
data2 = ['d', 'e']
s1 = pd.Series(data1, name='Apple')
s2 = pd.Series(data2, name='Orange')
df = pd.DataFrame([s1, s2])
df
#         0  1    2
# Apple   a  b    c
# Orange  d  e  NaN
```

このような場合は、 pd.concat を使用すると Series を縦に結合することができます。

```python
pd.concat([s1, s2], axis=1)
#   Apple Orange
# 0     a      d
# 1     b      e
# 2     c    NaN
```

## 1.7. DataFrame のコンストラクタ の dtype は全体に適用される、指定しなれば自動で決まる

```python
data1 = [0.5, 1.5, 2.5]
data2 = [10.1, 20.5, 30.9]
s1 = pd.Series(data1, name='x')
s2 = pd.Series(data2, name='y')
df = pd.DataFrame({s1.name: s1, s2.name: s2}, dtype=int)
df
#    x   y
# 0  0  10
# 1  1  20
# 2  2  30
```

## 1.8. DataFrame の columns の dtype の変換には astype 関数を使用するとできる
astype 関数の引数に辞書を使うと カラムごとにデータを変換できる

```python
data1 = [0.5, 1.5, 2.5]
data2 = [10, 20, 30]
s1 = pd.Series(data1, name='x')
s2 = pd.Series(data2, name='y')
df = pd.DataFrame({s1.name: s1, s2.name: s2}, dtype=int)
df2 = df.astype({s1.name: int, s2.name: float})
df2.dtypes #注意 DataFrame なので dtype dtypes
# x      int64
# y    float64
# dtype: object
```
	
astype 関数の引数が一つの dtype の場合 DataFrame 全体に適用される

```python
df3 = df.astype(str)
df3.dtypes
# x    object
# y    object
# dtype: object
```
	
## 1.9. df.loc[行ラベル] は Series なので注意

```python
data1 = [0.5, 1.5, 2.5]
data2 = [10, 20, 30]
s1 = pd.Series(data1, name='x')
s2 = pd.Series(data2, name='y')
df = pd.DataFrame({s1.name: s1, s2.name: s2}, dtype=int)
df.loc[0]
# x     0
# y    10
# Name: 0, dtype: int64
```
   
Series ではなく DataFrame が戻って欲しい場合は以下のように df.loc[[行ラベル]] のように書く

```python
df.loc[[0]]
#    x   y
# 0  0  10
```

# 2. その他 TIPS
  - エクセルで作成した csv のエンコーディングは sjis
  - csv にマルチバイト文字がある場合も適切に扱われるように見える
  - pandas が遅い時がある、同じ操作で numpy の方が早い時がある
  - 今後、DataFrame でSeriesを追加する時遅い時の時間計測を行えると良い

# 3. その他(勉強会の反省点等)
  - 説明は qiita、gist、github などで絵を入れられると良い
  - 開催について、午前か午後どちらかに分けた方が良い
  - データサイエンスの人と達が使う言葉を知れると良い
  - 機械学習の前のデータ、オープンデータがある、新潟市のものが使えるか?
  - 開催日について平日の夜とかが良い
  - 勉強時間当ててフィードバックするビジネスとかできそう?
  - Prototype Cafe 8/7 は空いてない
  - 平日２時間ほどの開催がよいのではないか

以上