Groupby & Sum 从一个特定值的出现到另一个特定值或相同值的出现
Posted
技术标签:
【中文标题】Groupby & Sum 从一个特定值的出现到另一个特定值或相同值的出现【英文标题】:Groupby & Sum from occurance of a particular value till the occurance of another particular value or the same value 【发布时间】:2020-04-04 11:46:32 【问题描述】:我有一个如下的数据框。
我想 groupby
'user' & 'eve' 和 sum
'Ses' 直到 100/200 和从 100 到 200。
此外,返回出现 100/200 的“名称”列的值。
如果在一百之后,没有 100 或 200(如 a & 123 或 a & 456 组中的最后一行),请忽略它。
User eve Ses ID Name
a 123 1 10 a
a 123 2 11 a
a 123 3 12 a
a 123 4 13 a
a 123 3 100 xyz
a 123 6 10 a
a 456 1 11 a
a 456 2 12 a
a 456 3 13 a
a 456 4 40 a
a 456 1 100 mno
a 456 14 10 a
a 456 7 20 a
a 456 8 30 a
a 456 12 200 pqr
a 456 10 10 a
b 123 1 20 a
b 123 2 30 a
b 123 3 40 a
b 123 4 50 a
b 123 1 70 a
b 123 6 100 abc
b 888 1 20 a
b 888 1 200 jkl
b 888 3 10 a
b 888 4 20 a
b 888 5 30 a
b 888 1 100 rrr
b 888 7 50 a
b 888 8 70 a
上述输入 df 的预期输出是下面的 df。
User eve Ses Name
a 123 13 xyz
a 456 11 mno
a 456 41 pqr
b 123 17 abc
b 888 2 jkl
b 888 13 rrr
【问题讨论】:
有人否决了这个问题。那个人能解释一下为什么吗?它会帮助我提高。 我没有投反对票,但您尝试了什么? 我不知道从哪里开始。我试过df.groupby(['User','eve'],sort=False).apply(lambda x: x[x['ID'].isin([100,200]),'ses'].sum())
,但我得到一个错误(这不会得到我想要的答案,但它仍然是一个开始)。
如果我这样做 df.index[(df['ID']==100) | (df['ID']==200)]
我得到了 100 和 200 所在位置的索引,谁能指导我可以使用它来获得我想要的输出?
【参考方案1】:
这是我的方法:
# valid IDs
df['valids'] = df['ID'].isin([100,200])
# mask the trailing non-hundred ids
heads = (df['ID'].where(df['valids'])
.groupby([df['User'],df['eve']])
.bfill().notnull()
)
df = df[heads]
# groupby and output:
(df.groupby(['User','eve', df['valids'].shift(fill_value=0).cumsum()],
as_index=False)
.agg('Ses':'sum', 'Name':'last')
)
输出:
User eve Ses Name
0 a 123 13 xyz
1 a 456 11 mno
2 a 456 41 pqr
3 b 123 17 abc
4 b 888 2 jkl
5 b 888 13 rrr
【讨论】:
谢谢。这有效:-)。这也快吗?在我的实际数据框中,大约有 1000 万行。谢谢。 取决于您的数据。通常几个列上的groupby
不会那么快。但这是我能想到的最优化的。
Quang,你能解释一下 bfill 是如何找到和 # 屏蔽尾随的非百个 id 的吗?这对我有帮助,我被困在那部分了。
@oppressionslayer 基本上,where
将所有非百人屏蔽为nan
。然后bfill()
用后面的一百个id 填充之前的所有nan
,除了尾随的nan
。
是的,这很有帮助,bfill 上的文档很简单(不存在),所以它肯定有助于我了解您是如何完成它的。以上是关于Groupby & Sum 从一个特定值的出现到另一个特定值或相同值的出现的主要内容,如果未能解决你的问题,请参考以下文章
LINQ:从列表中选择项目(Group By/Select/Sum & Max!)
使用 pandas groupby 根据另一个分类列对两个分类列应用 sum & count