Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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' になる

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

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

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

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 ではなく値が戻る。

s['b']
# 2

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

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 を辞書で作成する場合、辞書のそれぞれのバリューのリストの長さは同じでなければならない。そうでなければエラーとなる

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 の値には欠損値が設定される

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

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

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

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 を縦に結合することができます。

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

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

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 関数の引数に辞書を使うと カラムごとにデータを変換できる

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 全体に適用される

df3 = df.astype(str)
df3.dtypes
# x    object
# y    object
# dtype: object

1.9. df.loc[行ラベル] は Series なので注意

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[[行ラベル]] のように書く

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 は空いてない
  • 平日2時間ほどの開催がよいのではないか

以上

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away