Python 选择每组的最后一次观察

Python 选择每组的最后一次观察,python,pandas,Python,Pandas,有人要求选择熊猫df中每组的第一个观察,我对第一个和最后一个都感兴趣,除了编写for循环之外,我不知道一种有效的方法 我将修改他的例子,告诉你我在寻找什么 基本上有这样一个df: group_id 1 1 1 2 2 2 3 3 3 我想用一个变量来表示组中的最后一次观察: group_id indicator 1 0 1

有人要求选择熊猫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

首先,我们将创建一个索引位置列表,其中包含每个组的最后一个元素。您可以看到每个组的元素,如下所示:

>>> df.groupby('group_id').groups
{1: [0, 1, 2], 2: [3, 4, 5], 3: [6, 7, 8]}
我们使用列表理解来提取每个组索引值的最后一个索引位置(
idx[-1]

我们通过使用列表理解和三元运算符(即,如果条件为0,则为1),在索引中的每个元素上迭代,并检查它是否在
idx\u last\u组
列表中,将指示符分配给数据帧

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
使用,您可以执行以下操作:

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

如果将其作为一个整数对您来说非常重要。)


注意:

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

  • 正如Alexander所指出的,这假设数据帧按照示例中的顺序进行排序


  • 您可以通过
    groupby
    输入'id'并调用
    nth(-1)
    来获取每个组的最后一个条目,然后使用它来屏蔽df,并将'indicator'设置为
    1
    ,然后使用
    fillna
    将其余的设置为
    0

    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
    
    一行:

    data['indicator'] = (data.groupby('group_id').cumcount()==data.groupby('group_id')['any_other_column'].transform('size') -1 ).astype(int)`
    
    我们要做的是检查累计计数(返回与数据帧大小相同的向量)是否等于我们使用transform计算的“组大小-1”,因此它也返回与数据帧大小相同的向量

    我们需要使用其他列进行转换,因为它不允许您转换
    .groupby()
    变量,但这实际上可以是任何其他列,并且不会受到影响,因为它仅用于计算新指标。使用
    .astype(int)
    将其设置为二进制并完成。

    使用以下方法:


    这是一个很好的选择,但需要首先按照
    组id
    对数据帧进行排序(如本例所示)。
    data['indicator'] = (data.groupby('group_id').cumcount()==data.groupby('group_id')['any_other_column'].transform('size') -1 ).astype(int)`
    
    df=df.groupby('group_id').tail(1)