🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

6229閲覧

pandas pivot_tableの引数aggfuncについて

negi_

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2019/09/25 13:25

前提・実現したいこと

pandasのpivot_tableのaggfunc(集計方法)を、sumやcountを組み合わせた任意の方法で行うにはどうすればいいでしょうか。

例として、下記のようなDataFrameを考えたとき、storeとgenderのクロス集計を行い、
セルごとの顧客単価 SUM(revenue) / COUNT(customer) を求めるような集計をしたいのですが、
記法や、調べ方がよくかわりません。

ご教示いただけないでしょうか。

該当のソースコード

python

1import pandas as pd 2 3df = pd.DataFrame({ 4 'customer' : ['A','B','C','D','E','F','G','H','I','J','K','L','M'], 5 'store' : ['tokyo','tokyo','tokyo','tokyo','tokyo','osaka','osaka','osaka','osaka','nagoya','nagoya','nagoya','nagoya'], 6 'gender' : ['male','male','female','female','male','male','female','male','female','female','male','female','male'], 7 'revenue' : [200,600,400,300,500,200,400,300,300,700,100,600,100] 8 }) 9 10pd.pivot_table( 11 df, 12 values = ['revenue','customer'], 13 aggfunc = {'revenue':'sum','customer':'count'}, 14 index = 'store', 15 columns = 'gender' 16)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

はじめに(本題とはあまり関係ありませんが)、上記の例の場合、df['revenue'].count()df['customer'].count() と同じ値となる、つまりdf['revenue'].sum() / df['customer'].count()df['revenue'].sum() / df['revenue'].count() と置き換えられるので、その結果

Python

1res = pd.pivot_table( 2 df, 3 aggfunc = {'revenue': 'mean'}, 4 index = 'store', 5 columns = 'gender' 6)

で良いのではないかと思うのですがどうでしょうか?


それはそれとしてここからが本題なのですが、質問のように複数の列を使って計算にてピボットテーブルを作成したい場合は、pandas.pivot_table()ではなくGroupBy.apply()を使うと良いかと思います。
今回の例の場合は DataFrame.groupby() の引数に縦軸に割り当てたい'store'と横軸に割り当てたい'gender'を指定し、apply()にて目的となる値を計算し、出力されたDataFrameをunstack()することにてピボットテーブルが作成できます。

Python

1def func(data): 2 return data['revenue'].sum() / data['customer'].count() 3 4res = df.groupby(['store','gender']).apply(func).unstack() 5#gender female male 6#store 7#nagoya 650.0 100.000000 8#osaka 350.0 250.000000 9#tokyo 350.0 433.333333

投稿2019/09/26 02:06

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

マルチインデックスを解除したのではだめでしょうか?

python

1df1 = pd.pivot_table( df, values = ['revenue','customer'], aggfunc = {'revenue':'sum','customer':'count'}, index = 'store', columns = 'gender') 2 3df1 4 5# マルチインデックスを解除 6df1.columns = ['_'.join(col) for col in df1.columns] 7df1 8 9df1["price_female"] = df1["revenue_female"] / df1["customer_female"] 10df1["price_male"] = df1["revenue_male"] / df1["customer_male"] 11df1

投稿2019/09/25 14:30

barobaro

総合スコア1286

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問