0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pandas の groupby が Empty DataFrame で失敗する件

Last updated at Posted at 2021-09-09

なんか pandas の groupby の計算がうまく動かないので、同じように困っている人(がもしいたら、、)のための情報です。

うまくいく使い方

pandasでは、groupbyでグループ分けして、平均とかを計算できます。

import pandas as pd
df = pd.DataFrame({
    'city' : ['tokyo', 'tokyo', 'osaka', 'osaka'],
    'month': ['April', 'May', 'April','May'],
    'price': [200, 300, 150, 250]
})
print(df.groupby('city').mean())

出力

       price
city        
osaka  200.0
tokyo  250.0

うまく行かない場合

ところが、空の DataFrame を最初に作っておいて、行を追加して実行すると、うまく動きません。

df0 = pd.DataFrame(columns=['city','month','price'])
df0 = df0.append({'city':'tokyo', 'month':'April', 'price':200}, ignore_index=True)
df0 = df0.append({'city':'tokyo', 'month':'May', 'price':300}, ignore_index=True)
df0 = df0.append({'city':'osaka', 'month':'April', 'price':150}, ignore_index=True)
df0 = df0.append({'city':'osaka', 'month':'May', 'price':250}, ignore_index=True)
print(df0.groupby('city').mean())

結果

Empty DataFrame
Columns: []
Index: [osaka, tokyo]

dfとdf0は、print しただけでは全く同じ。

print(df)
print(df0)
print(type(df))
print(type(df0))

出力

    city  month  price
0  tokyo  April    200
1  tokyo    May    300
2  osaka  April    150
3  osaka    May    250
    city  month price
0  tokyo  April   200
1  tokyo    May   300
2  osaka  April   150
3  osaka    May   250
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.frame.DataFrame'>

(あれ?良く見ると、空白1個分ずれているけど、これが何か悪さしているのかな?)

少し変えると動く

ちなみに、空の DataFrame の作り方によっては、うまくいく場合もある。

df0 = pd.DataFrame({'city':[], 'month':[], 'price':[]})
df0 = df0.append({'city':'tokyo', 'month':'April', 'price':200}, ignore_index=True)
df0 = df0.append({'city':'tokyo', 'month':'May', 'price':300}, ignore_index=True)
df0 = df0.append({'city':'osaka', 'month':'April', 'price':150}, ignore_index=True)
df0 = df0.append({'city':'osaka', 'month':'May', 'price':250}, ignore_index=True)
print(df0.groupby('city').mean())

出力

       price
city        
osaka  200.0
tokyo  250.0

感想

pandasの公式マニュアルを見ても、empty DataFrame の作り方は見つからないので、そもそもこういう使い方が良くない使い方のような感じです。

解決

公式サイトを良く見たら、
https://pandas.pydata.org/docs/user_guide/groupby.html?highlight=empty#other-useful-features
「以下のように書け」と書いてありました。これなら動きます。

df0.groupby(['city']).agg({'price': 'mean'})

何故こうなるかというと、price の型が異なっていて、

>>> df.dtypes
city     object
month    object
price     int64
dtype: object
>>> df0.dtypes
city     object
month    object
price    object
dtype: object

dfはすべてint64だと分かっているので、mean( ) の計算ができるけど、df0 は何が来るか分からないので mean( ) の計算は出来ないと認識されるため。agg を使うと、「そんなの良いから計算してよ」ということで計算してくれる。
(というのが私の理解)
ちなみに、「少し変えると動く」の方法だと、price は float だと推測される。型の推定のアルゴリズムが違うっぽい。

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?