在分组的熊猫数据框中将行放在最大值之后

时间:2018-07-06 16:09:34

标签: python pandas dataframe pandas-groupby

我有一个可以分组的按日期排序的数据框。我正在尝试做的是将变量(人)分组,确定每个组(人)的最大值(权重),然后删除(日期)最大值之后的所有行。

以下是数据示例:

df = pd.DataFrame({'Person': 1,1,1,1,1,2,2,2,2,2],'Date': '1/1/2015','2/1/2015','3/1/2015','4/1/2015','5/1/2015','6/1/2011','7/1/2011','8/1/2011','9/1/2011','10/1/2011'], 'MonthNo':[1,2,3,4,5,1,2,3,4,5], 'Weight':[100,110,115,112,108,205,210,211,215,206]})

    Date      MonthNo  Person  Weight
0   1/1/2015        1       1     100
1   2/1/2015        2       1     110
2   3/1/2015        3       1     115
3   4/1/2015        4       1     112
4   5/1/2015        5       1     108
5   6/1/2011        1       2     205
6   7/1/2011        2       2     210
7   8/1/2011        3       2     211
8   9/1/2011        4       2     215
9  10/1/2011        5       2     206

这就是我想要的结果:

    Date      MonthNo  Person  Weight
0   1/1/2015        1       1     100
1   2/1/2015        2       1     110
2   3/1/2015        3       1     115
5   6/1/2011        1       2     205
6   7/1/2011        2       2     210
7   8/1/2011        3       2     211
8   9/1/2011        4       2     215

我认为值得注意的是,开始日期可能会不一致,并且最大值可能会出现在不同的时间。

我的想法是找到每个组的最大值,获取该组最大值的MonthNo,然后丢弃MonthNo大于Max Weight MonthNo的任何行。到目前为止,我已经能够按组获取最大值,但是无法基于此进行比较。

请让我知道我是否可以编辑/提供更多信息,这里还没有发布很多问题!感谢您的帮助,如果我的格式/问题不清楚,请抱歉。

2 个答案:

答案 0 :(得分:4)

idxmaxgroupby一起使用

df.groupby('Person',sort=False).apply(lambda x  : x.reset_index(drop=True).iloc[:x.reset_index(drop=True).Weight.idxmax()+1,:])

Out[131]: 
              Date  MonthNo  Person  Weight
Person                                     
1      0  1/1/2015        1       1     100
       1  2/1/2015        2       1     110
       2  3/1/2015        3       1     115
2      0  6/1/2011        1       2     205
       1  7/1/2011        2       2     210
       2  8/1/2011        3       2     211
       3  9/1/2011        4       2     215

答案 1 :(得分:4)

您可以将groupby.transformidxmax一起使用。根据数据框的结构,前两个步骤可能不是必需的。

# convert Date to datetime
df['Date'] = pd.to_datetime(df['Date'])

# sort by Person and Date to make index usable for next step
df = df.sort_values(['Person', 'Date']).reset_index(drop=True)

# filter for index less than idxmax transformed by group
df = df[df.index <= df.groupby('Person')['Weight'].transform('idxmax')]

print(df)

        Date  MonthNo  Person  Weight
0 2015-01-01        1       1     100
1 2015-02-01        2       1     110
2 2015-03-01        3       1     115
5 2011-06-01        1       2     205
6 2011-07-01        2       2     210
7 2011-08-01        3       2     211
8 2011-09-01        4       2     215