选择每组最后一次观察

时间:2015-11-24 18:23:18

标签: python pandas

有人要求在pandas df中选择每组的第一个观察,我对第一个和最后一个感兴趣,除了编写for循环之外,我不知道这样做的有效方法。

我要修改他的例子来告诉你我在寻找什么 基本上有这样的df:

group_id 
1          
1        
1        
2        
2        
2        
3        
3        
3        

我想有一个变量来指示组中的最后一次观察:

group_id indicator
1        0  
1        0
1        1
2        0
2        0
2        1
3        0
3        0
3        1

5 个答案:

答案 0 :(得分:1)

首先,我们将创建一个包含每个组的最后一个元素的索引位置列表。您可以按如下方式查看每个组的元素:

>>> df.groupby('group_id').groups
{1: [0, 1, 2], 2: [3, 4, 5], 3: [6, 7, 8]}

我们使用列表推导来提取每个组索引值的最后一个索引位置(idx[-1])。

我们使用列表推导和三元运算符(即if条件为0时为1)将指标分配给数据帧,迭代索引中的每个元素并检查它是否在idx_last_group列表中。< / p>

idx_last_group = [idx[-1] for idx in df.groupby('group_id').groups.values()]
df['indicator'] = [1 if idx in idx_last_group else 0 for idx in df.index]

>>> df
   group_id  indicator
0         1          0
1         1          0
2         1          1
3         2          0
4         2          0
5         2          1
6         3          0
7         3          0
8         3          1

答案 1 :(得分:1)

使用pandas.shift,您可以执行以下操作:

df['group_indicator'] = df.group_id != df.group_id.shift(-1)

(或

df['group_indicator'] = (df.group_id != df.group_id.shift(-1)).astype(int)

如果将它作为整数实际上很重要。)

注意:

  1. 对于大型数据集,这应该比列表理解(更不用说循环)快得多。

  2. 正如Alexander所说,这假设DataFrame按照示例中的顺序排序。

答案 2 :(得分:0)

您可以groupby&#39; id&#39;并致电nth(-1)获取每个组的最后一个条目,然后使用它来屏蔽df并设置指示符&#39;使用1 <{1}} 0然后使用fillna进行其余工作:

In [21]:
df.loc[df.groupby('group_id')['group_id'].nth(-1).index,'indicator'] = 1
df['indicator'].fillna(0, inplace=True)
df

Out[21]:
   group_id  indicator
0         1          0
1         1          0
2         1          1
3         2          0
4         2          0
5         2          1
6         3          0
7         3          0
8         3          1

以下是groupby的输出:

In [22]:
df.groupby('group_id')['group_id'].nth(-1)

Out[22]:
2    1
5    2
8    3
Name: group_id, dtype: int64

答案 3 :(得分:0)

一行:

data['indicator'] = (data.groupby('group_id').cumcount()==data.groupby('group_id')['any_other_column'].transform('size') -1 ).astype(int)

我们要做的是检查累计计数(返回与数据帧大小相同的向量)是否等于我们使用转换计算的“组的大小-1”,因此它也返回相同大小的向量作为数据框。

我们需要使用其他一些列进行转换,因为它不会让您转换.groupby()变量,但是它实际上可以是任何其他列,并且不会受到影响,因为它仅用于计算新列指示符。使用.astype(int)使其成为二进制文件并完成:)

答案 4 :(得分:0)

使用 .tail 方法:

df=df.groupby('group_id').tail(1)