Python 按数量和比例分组

Python 按数量和比例分组,python,pandas,Python,Pandas,我正试图做一些我知道必须是基本的事情,但我绞尽脑汁想弄明白。我希望每个组的比例和计数可用于任意级别的组BY: import pandas as pd df = pd.DataFrame({'A': [1, 0, 1, 0, 1, 0, 0, 0], 'B': ['A'] * 4 + ['B'] * 4}) gb = df.groupby(['A', 'B']).size() prop_gb = gb / gb.groupby(level=0).sum() prop_gb现在是: prop

我正试图做一些我知道必须是基本的事情,但我绞尽脑汁想弄明白。我希望每个组的比例和计数可用于任意级别的组BY:

import pandas as pd

df = pd.DataFrame({'A': [1, 0, 1, 0, 1, 0, 0, 0], 'B': ['A'] * 4 + ['B'] * 4})

gb = df.groupby(['A', 'B']).size()

prop_gb = gb / gb.groupby(level=0).sum()
prop_gb
现在是:

prop_gb
Out[116]: 
A  B
0  A    0.400000
   B    0.600000
1  A    0.666667
   B    0.333333
dtype: float64
不过,我最终还是想要这样:

A  B        prop  count
0  A    0.400000      2
   B    0.600000      3
1  A    0.666667      2
   B    0.333333      1
我曾尝试将两个
pandas.Series
对象、
gb
prop\u gb
合并到一起,将它们转换成字典并以这种方式“连接”它们,但我知道必须有一种本地pandas方法来实现这一点

这在技术上实现了我想要的:

desired = {k: (v, prop_gb.to_dict()[k]) for k, v in gb.to_dict().items()}
desired
{(0, 'A'): (2, 0.40000000000000002),
 (0, 'B'): (3, 0.59999999999999998),
 (1, 'A'): (2, 0.66666666666666663),
 (1, 'B'): (1, 0.33333333333333331)}

您可以使用
to_frame
创建一个数据帧,并添加
prop
列:

>>> desired = df.groupby(['A', 'B']).size().to_frame('count')
>>> desired['prop'] = gb / gb.groupby(level=0).sum()
>>> desired
     count      prop
A B                 
0 A      2  0.400000
  B      3  0.600000
1 A      2  0.666667
  B      1  0.333333
或者,从2系列中创建一个新框架:

>>> pd.DataFrame(dict(prop=prop_gb, count=gb))
     count      prop
A B                 
0 A      2  0.400000
  B      3  0.600000
1 A      2  0.666667
  B      1  0.333333

Concat已创建的两个系列:

df = pd.concat([prop_gb, gb], axis=1)
df.columns = ['prop', 'count']

df

         prop  count
A B
0 A  0.400000  2
  B  0.600000  3
1 A  0.666667  2
  B  0.333333  1

您可以在一个表达式中生成这些值,如下所示:

df.groupby(['A', 'B']).size().agg(
  {'count': lambda x: x, 'prop':lambda x: x / x.sum(level=0)}
  ).unstack(level=0).reset_index()
#    A  B  count      prop
# 0  0  A    2.0  0.400000
# 1  0  B    3.0  0.600000
# 2  1  A    2.0  0.666667
# 3  1  B    1.0  0.333333