ピボットテーブルのaggfuncを色々試してみる

2020年12月21日

ピボットテーブルのaggfuncを色々試してみる

ピボットテーブルはデータフレームを見やすいように整形してくれるみたいです。
さらに「aggfunc」を使用する事でさらにデータを加工できるみたいです。
それでは早速使用してみたいと思います。

参考:pandasのピボットテーブルでカテゴリ毎の統計量などを算出

aggfunc


#データ用意
fruits = [
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202001},
    {'item': 'orange', 'price': 300, 'stock': 30, 'country': 'japan', 'date':202001},
    {'item': 'banana', 'price': 150, 'stock': 40, 'country': 'japan', 'date':202001},
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202002},
    {'item': 'orange', 'price': 400, 'stock': 28, 'country': 'japan', 'date':202002},
    {'item': 'banana', 'price': 100, 'stock': 45, 'country': 'japan', 'date':202002},
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202003},
    {'item': 'orange', 'price': 500, 'stock': 22, 'country': 'japan', 'date':202003},
    {'item': 'banana', 'price': 50,  'stock': 60, 'country': 'japan', 'date':202003}
]

#データフレーム化
df_fruits = pd.DataFrame(fruits)
#print(df_fruits)
#     item  price  stock country    date
#0   apple    200     20   japan  202001
#1  orange    300     30   japan  202001
#2  banana    150     40   japan  202001
#3   apple    200     20   japan  202002
#4  orange    400     28   japan  202002
#5  banana    100     45   japan  202002
#6   apple    200     20   japan  202003
#7  orange    500     22   japan  202003
#8  banana     50     60   japan  202003

#ピボットテーブル化
df = df.pivot_table(index="item", columns="date", values=["price", "stock"])
#print(df)
#        price                stock              
#date   202001 202002 202003 202001 202002 202003
#item                                            
#apple     200    200    200     20     20     20
#banana    150    100     50     40     45     60
#orange    300    400    500     30     28     22

上記は日本産のデータのみですが、例えばここにアメリカ産のデータを追加してみます。


#データ用意
fruits = [
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202001},
    {'item': 'orange', 'price': 300, 'stock': 30, 'country': 'japan', 'date':202001},
    {'item': 'banana', 'price': 150, 'stock': 40, 'country': 'japan', 'date':202001},
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202002},
    {'item': 'orange', 'price': 400, 'stock': 28, 'country': 'japan', 'date':202002},
    {'item': 'banana', 'price': 100, 'stock': 45, 'country': 'japan', 'date':202002},
    {'item': 'apple',  'price': 200, 'stock': 20, 'country': 'japan', 'date':202003},
    {'item': 'orange', 'price': 500, 'stock': 22, 'country': 'japan', 'date':202003},
    {'item': 'banana', 'price': 50,  'stock': 60, 'country': 'japan', 'date':202003},

    {'item': 'apple',  'price': 400,  'stock': 20, 'country': 'america', 'date':202001},
    {'item': 'orange', 'price': 600,  'stock': 30, 'country': 'america', 'date':202001},
    {'item': 'banana', 'price': 300,  'stock': 40, 'country': 'america', 'date':202001},
    {'item': 'apple',  'price': 400,  'stock': 20, 'country': 'america', 'date':202002},
    {'item': 'orange', 'price': 800,  'stock': 28, 'country': 'america', 'date':202002},
    {'item': 'banana', 'price': 200,  'stock': 45, 'country': 'america', 'date':202002},
    {'item': 'apple',  'price': 400,  'stock': 20, 'country': 'america', 'date':202003},
    {'item': 'orange', 'price': 1000, 'stock': 22, 'country': 'america', 'date':202003},
    {'item': 'banana', 'price': 100,  'stock': 60, 'country': 'america', 'date':202003}
]

#データフレーム化
df = pd.DataFrame(fruits)
#print(df)
#      item  price  stock  country    date
#0    apple    200     20    japan  202001
#1   orange    300     30    japan  202001
#2   banana    150     40    japan  202001
#3    apple    200     20    japan  202002
#4   orange    400     28    japan  202002
#5   banana    100     45    japan  202002
#6    apple    200     20    japan  202003
#7   orange    500     22    japan  202003
#8   banana     50     60    japan  202003
#9    apple    400     20  america  202001
#10  orange    600     30  america  202001
#11  banana    300     40  america  202001
#12   apple    400     20  america  202002
#13  orange    800     28  america  202002
#14  banana    200     45  america  202002
#15   apple    400     20  america  202003
#16  orange   1000     22  america  202003
#17  banana    100     60  america  202003

#ピボットテーブル化
df = df.pivot_table(index="item", columns="date", values=["price", "stock"])
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple     300    300    300     20     20     20
# banana    225    150     75     40     45     60
# orange    450    600    750     30     28     22

「japan」のデータのみで作成したとピボットテーブルと「japan」と「america」のデータで作成したピボットテーブルを見比べてみます。


#japan
#        price                stock              
#date   202001 202002 202003 202001 202002 202003
#item                                            
#apple     200    200    200     20     20     20
#banana    150    100     50     40     45     60
#orange    300    400    500     30     28     22

#japan&america
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple     300    300    300     20     20     20
# banana    225    150     75     40     45     60
# orange    450    600    750     30     28     22

なるほど、データが違いますね。
これは「japan」「america」の平均を出力しているかららしいです。
引数で「aggfunc」を指定していません。デフォルトでは「aggfunc=numpy.mean()」が適用されるみたです。


#ピボットテーブル化(mean->日本とアメリカの平均値)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=np.mean)
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple     300    300    300     20     20     20
# banana    225    150     75     40     45     60
# orange    450    600    750     30     28     22

#ピボットテーブル化(min->日本とアメリカの最小値)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=np.min)
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple     200    200    200     20     20     20
# banana    150    100     50     40     45     60
# orange    300    400    500     30     28     22

#ピボットテーブル化(min,max->日本とアメリカの最小値と最大値)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=[np.min, np.max])
# print(df)
#          amin                                      amax                                   
#         price                stock                price                stock              
# date   202001 202002 202003 202001 202002 202003 202001 202002 202003 202001 202002 202003
# item                                                                                      
# apple     200    200    200     20     20     20    400    400    400     20     20     20
# banana    150    100     50     40     45     60    300    200    100     40     45     60
# orange    300    400    500     30     28     22    600    800   1000     30     28     22

#ピボットテーブル化(sum->日本とアメリカの合計値)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=np.sum)
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple     600    600    600     40     40     40
# banana    450    300    150     80     90    120
# orange    900   1200   1500     60     56     44

「aggfunc=len」はカテゴリ毎の出現回数が算出できるとの事。


#ピボットテーブル化(mean->出現回数)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=len)
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple       2      2      2      2      2      2
# banana      2      2      2      2      2      2
# orange      2      2      2      2      2      2

すべて2なのが確認できる。これは現在「japan」と「america」が該当しているからみたいです。
配列に下記の行を付け足してみます。


{'item': 'apple',  'price': 400,  'stock': 20, 'country': 'itary', 'date':202001},

再度「aggfunc=len」を確認してみます。


#ピボットテーブル化(mean->出現回数)
df = df.pivot_table(index="item", columns="date", values=["price", "stock"], aggfunc=len)
# print(df)
#         price                stock              
# date   202001 202002 202003 202001 202002 202003
# item                                            
# apple       3      2      2      3      2      2
# banana      2      2      2      2      2      2
# orange      2      2      2      2      2      2

「apple行のprice>202001列」と「apple行のstock>202001列」が「3」になったのが確認できました。

2020年12月21日