有人要求在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
答案 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)
如果将它作为整数实际上很重要。)
注意:
对于大型数据集,这应该比列表理解(更不用说循环)快得多。
正如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)