Pandas按组求和nlargest

28

我正在尝试在Pandas中同时使用groupbynlargestsum函数,但是无法使其正常运行。

State    County    Population
Alabama  a         100
Alabama  b         50
Alabama  c         40
Alabama  d         5
Alabama  e         1
...
Wyoming  a.51      180
Wyoming  b.51      150
Wyoming  c.51      56
Wyoming  d.51      5
我想使用 groupby 按州选择,然后按人口获取前两个县。 然后仅使用这些顶部2个县的人口数字来为该州获得总和。
最终,我将拥有一个列表,其中包含州和其前两个县的人口。
我可以让 groupbynlargest 工作,但是获取 nlargest(2) 的总和是一项挑战。
我现在有的代码行只是: df.groupby('State')['Population'].nlargest(2)
2个回答

47

在执行 groupby 后,您可以使用 apply

df.groupby('State')['Population'].apply(lambda grp: grp.nlargest(2).sum())

我认为你遇到的问题是df.groupby('State')['Population'].nlargest(2)将返回一个DataFrame,因此您不能再进行分组级别的操作。通常,如果您想在一个组中执行多个操作,您需要使用apply/agg

结果输出如下:

State
Alabama    150
Wyoming    330

编辑

根据 @cs95 的建议,有一个稍微更清晰的方法:

df.groupby('State')['Population'].nlargest(2).sum(level=0)

尽管如此,在较大的数据框上使用 apply 比这种方法稍慢。

使用以下设置:

import numpy as np
import pandas as pd
from string import ascii_letters

n = 10**6
df = pd.DataFrame({'A': np.random.choice(list(ascii_letters), size=n),
                   'B': np.random.randint(10**7, size=n)})

我得到了以下时间:

In [3]: %timeit df.groupby('A')['B'].apply(lambda grp: grp.nlargest(2).sum())
103 ms ± 1.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [4]: %timeit df.groupby('A')['B'].nlargest(2).sum(level=0)
147 ms ± 3.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

较慢的性能可能是由于sum中的level kwarg在底层执行了第二个groupby


3
使用 df.groupby('State')['Population'].nlargest(2).sum(level=0) 来替换 apply 方法即可解决该问题。请注意不要改变原本的意思。 - cs95
2
@cᴏʟᴅsᴘᴇᴇᴅ:当数据框的大小相当大时,您提出的解决方案.nlargest(2).sum(level=0)实际上比使用apply更慢。在sum中使用的level关键字参数在幕后执行第二个分组操作,我猜这就是额外开销的来源。 - root
3
这很令人惊讶。因此,一个groupby + apply胜过两个groupby。学到了新东西,干杯! - cs95
1
如果“county”不是唯一的,您的解决方案是否仍然有效?想象一下,有两行数据:Alabama;e;2Alabama;e;39?那么会考虑e而不是c吗? - Koray Tugay

7
使用agg,分组逻辑如下: df.groupby('State').agg({'Population': {lambda x: x.nlargest(2).sum() }}) 这将产生另一个数据帧对象;您可以查询它以查找最具人口的州等信息。
           Population
State
Alabama    150
Wyoming    330

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接