Pandasのgroupbyによる合計の割合 質問する

Pandasのgroupbyによる合計の割合 質問する

これは明らかに単純ですが、NumPy 初心者の私には行き詰まっています。

州、オフィス ID、およびそのオフィスの売上の 3 つの列を含む CSV ファイルがあります。

特定の州におけるオフィスごとの売上の割合を計算したい (各州のすべての割合の合計は 100%)。

df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
                   'office_id': list(range(1, 7)) * 2,
                   'sales': [np.random.randint(100000, 999999)
                             for _ in range(12)]})

df.groupby(['state', 'office_id']).agg({'sales': 'sum'})

結果は次のようになります:

                  sales
state office_id        
AZ    2          839507
      4          373917
      6          347225
CA    1          798585
      3          890850
      5          454423
CO    1          819975
      3          202969
      5          614011
WA    2          163942
      4          369858
      6          959285

分数を計算するために、全体の合計を出すために、stateのレベルまで「到達」する方法がわかりません。groupbysalesstate

ベストアンサー1

2022-03 アップデート

この答えによるキャンサーを使用すると、transform私の最初の回答よりもはるかに良くなります。

df['sales'] / df.groupby('state')['sales'].transform('sum')

感謝このコメントによるポール・ルジューそれを表面化させるために。

オリジナル回答(2014)

ポールHの回答2 番目のオブジェクトを作成する必要があるのは正しいですgroupbyが、パーセンテージはもっと簡単な方法で計算できます。つまり、列をその合計で割るだけですgroupby。Paul state_officeHsalesの回答の冒頭をコピーします。

# From Paul H
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
                   'office_id': list(range(1, 7)) * 2,
                   'sales': [np.random.randint(100000, 999999)
                             for _ in range(12)]})
state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
# Change: groupby state_office and divide by sum
state_pcts = state_office.groupby(level=0).apply(lambda x:
                                                 100 * x / float(x.sum()))

戻り値:

                     sales
state office_id           
AZ    2          16.981365
      4          19.250033
      6          63.768601
CA    1          19.331879
      3          33.858747
      5          46.809373
CO    1          36.851857
      3          19.874290
      5          43.273852
WA    2          34.707233
      4          35.511259
      6          29.781508

おすすめ記事