yoshidabenjiro's blog

respect Yoshua Bengio.

pandas で pivot_table が機能しない場合の対処(DataError: No numeric types to aggregate)

こんにちは。吉田弁二郎です。

Python でデータ分析をする際には pandas を使うのが標準的です。特に、通常はデータを横持ちで格納しているDBから抽出してクロス集計をするというような時には、pandas.pivot_table を使うと便利ですね。最近この関数がうまく使えなかった経験をしたので、対策を記録しておきます。(小ネタ)

状況

import pandas as pd
pd.__version__  # 0.19.2

pandas.pivot_table は、オプション引数を aggfunc='count' とすることで該当データ数を集計することができます(デフォルトでは 'mean' が指定されている)。次のようなデータがあるとしましょう。

data = pd.DataFrame({'y': ['a', 'b', 'a'], 'z': ['A', 'B', 'A']})
# y z
# a A
# b B
# a A

これに対して、y を行、z を列としたデータ数集計をしたいとします。期待している出力は、次のテーブルです。

#   A    B
# a 2    nan
# b nan  1

問題

上記のデータに対して安直に data.pivot_table を実行すると、DataError が生じます。

data.pivot_table(index='y', columns='z', aggfunc='count')
# DataError: No numeric types to aggregate

原因と対策

原因は、aggfunc に与えるべきデータが存在していないことです。内部的には、引数として与えられている index と columns を合わせて groupby のキーとして与えた後、data を groupby して aggfunc を適用するのですが、この段階で集計対象のデータ(= index でも columns でも指定されていない変数)が存在せずエラーが出るという感じです。

そのため、意図した出力を得るためには、ダミーデータ列を追加すればOKです(階層的インデックス付けされた DataFrame が返る)。

data['counts'] = [1, 1, 1]
data.pivot_table(index='y', columns='z', aggfunc='count')
#     counts
# z | A    B
# y
# a   2    nan
# b   nan  1


Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理