我看到了许多解决固定条件的方法,这些方法可以固定过滤条件(“嘿,按名称分组,然后寻找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分组中的同一人进行匹配?
另一种选择是在思考“嘿,也许有一个expand()版本可以从第一张唱片开始就可以了”
让我的手指交叉,上述方法之一在方向上是正确的,并且有些英雄出现说:“哦,你太近了,只需添加这小部分!”
答案 0 :(得分:0)
“哦,您太近了,只需添加这一小部分!”
请参阅下文,了解更多内容。
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