在使用groupby-specifc过滤条件的groupby之后进行熊猫过滤?

时间:2019-03-06 23:18:20

标签: pandas 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分组中的同一人进行匹配?

另一种选择是在思考“嘿,也许有一个expand()版本可以从第一张唱片开始就可以了”

让我的手指交叉,上述方法之一在方向上是正确的,并且有些英雄出现说:“哦,你太近了,只需添加这小部分!”

1 个答案:

答案 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