pandas - 使用 groupby-specific 过滤条件进行 groupby 后的 pandas 过滤?
问题描述
我已经看到了许多“在 groupby 之后过滤”的出色解决方案,其中过滤条件是固定的(“嘿,按名称分组,然后查找 21 岁以上的每个人”,其中 21 是固定的。我是寻找一种基于 groupby 的结果进行过滤的方法。
例子:
df = pd.DataFrame({'person':['Sue', 'Sue', 'Sue', 'Bill', 'Alfonso'],
'date': ['2019-01-01','2019-01-02', '2019-01-03','2019-02-01', '2019-03-01'],
'my_value': [5,10,20,10,5],
'my_other_value': [3,2,9,6,8]})
我希望能够按照以下方式提出一个问题:“从一个人第一次的 my_value 为 10 开始,告诉我所有连续记录的 my_other_value 的平均值”。
在示例中,Sue 具有 my_value == 10 的第一个日期是 2019-01-02,因此她对 my_other_value 的均值是 (2+9)/2 = 5.5,它来自 2019-01-02 和 2019- 01-03。比尔只有一个条目,但它的 my_value 确实为 10,因此他的 my_other_value 平均值为 6。可悲的是,阿方索的 my_value 从未为 10,因此他甚至没有被包括在最终计数中
所以,我开始
df2 = df.query('my_value == 10').groupby('person').first().reset_index()
这让我第一次有一个人的 my_value 为 10。由此我知道这个人和它发生的日期。所以用英语,我现在想为那个人过滤这些结果,这样我就可以做一个 .mean() 但只包括那个人的行 >= 我从调用 first() 中学到的日期。当然,我被困住了。
我有点希望这样的事情会起作用:
df3 = df.groupby('person').apply( lambda x: x['date'] >= df2['date']).mean()
但我知道这不能真正起作用,因为 lambda 怎么知道将 df.groupby() 中的正确人与 df2 分组中的同一人匹配?
另一种选择是想“嘿,也许有一个版本的扩展()可以从第一条记录以外的东西开始”
我的手指交叉着上面的方法之一是方向正确的,一些英雄出现说“哦,你是如此接近,只需添加这个额外的小部分!”
解决方案
“哦,你这么近,就加上这个小额外部分!”
请参阅下面的额外部分。
df = pd.DataFrame({'person':['Sue', 'Sue', 'Sue', 'Bill', 'Alfonso'],
'date': ['2019-01-01','2019-01-02', '2019-01-03','2019-02-01', '2019-03-01'],
'my_value': [5,10,20,10,5],
'my_other_value': [3,2,9,6,8]})
df = df.sort_values(['person', 'date']).reset_index(drop=True)
>>> df
person date my_value my_other_value
0 Alfonso 2019-03-01 5 8
1 Bill 2019-02-01 10 6
2 Sue 2019-01-01 5 3
3 Sue 2019-01-02 10 2
4 Sue 2019-01-03 20 9
查找第一个日期 my_value == 10
df2 = df.query('my_value == 10').groupby('person').first()['date'].reset_index()
df2 = df2.rename(columns={'date': 'first_date'})
>>> df2
person first_date
0 Bill 2019-02-01
1 Sue 2019-01-02
合并数据框
df_merged = pd.merge(df, df2, how='left', on=['person'])
>>> df_merged
person date my_value my_other_value first_date
0 Alfonso 2019-03-01 5 8 NaN
1 Bill 2019-02-01 10 6 2019-02-01
2 Sue 2019-01-01 5 3 2019-01-02
3 Sue 2019-01-02 10 2 2019-01-02
4 Sue 2019-01-03 20 9 2019-01-02
计算平均值 my_other_value
grouped = df_merged[df_merged['date'] >= df_merged['first_date']].groupby('person')
>>> grouped['my_other_value'].mean()
person
Bill 6.0
Sue 5.5
Name: my_other_value, dtype: float64
推荐阅读
- javascript - 该函数的参数名称隐藏的函数名称
- javascript - 我怎样才能找到所有正确的组合?
- html - 之间的区别
和
- amazon-web-services - iam-user-unused-credentials-check 究竟是如何工作的?
- java - 按名称显示实体字段
- python - 如何创建一个 python 脚本来 ssh 并在多个 linux 设备上运行命令
- vue.js - 仅打印 FullCalendar 时间轴组件
- node.js - node.js:将 json 转换为数组
- javascript - D3 雷达图为所有多边形线提供相同的颜色
- pdf - Dompdf 给了我一个空的 pdf