如何在pandas中获取groupby()中的最后一条记录?

4
我有一个名为df的数据框,其中包含每个学生的多条记录。经常我想获取最后一个时间戳的记录。
如何以最佳方式实现这一目标?之前我一直使用last()函数,但它只返回最后一个非空值,而我实际上只想要最后一个值,无论是否为空。
使用apply(lambda r: r.iloc[-1])可以实现,但代码看起来不太美观(我讨厌使用apply函数,并且根据经验感觉它可能会慢和低效,很可能是因为apply的原因)。
请问有没有更好的方法来实现这个需求?
(Pdb) df = pd.DataFrame([["A",2,3],["B",5,6],["A",np.NaN,4]], columns=["student", "value_a", "timestamp"]).sort_values("timestamp")
(Pdb) df
  student  value_a  timestamp
0       A      2.0          3
2       A      NaN          4
1       B      5.0          6

(Pdb) df.groupby("student").last()
# This gives the wrong answer
         value_a  timestamp
student                    
A            2.0          4
B            5.0          6

(Pdb) df.groupby("student").apply(lambda r: r.iloc[-1])
# This gives the right answer but feels inefficient
        student  value_a  timestamp
student                            
A             A      NaN          4
B             B      5.0          6
3个回答

5
一种选择是使用groupby.tail
df.groupby('student').tail(1)

输出:

  student  value_a  timestamp
2       A      NaN          4
1       B      5.0          6

请注意,如果您想要获取最后的时间戳,另一个选择是使用groupby.idxmax进行索引:
df.loc[df.groupby('student')['timestamp'].idxmax()]

请注意:这几乎是我想要的,只是它会导致输出结果不被分组列索引。有时候这正是你所需要的! - YGA
注意:这几乎是我想要的,只是它会导致输出结果不被分组列索引。有时候这正是你所需要的! - YGA

4
你可以尝试使用`.nth`:
out = df.groupby('student').nth(-1)
print(out)

输出:

         value_a  timestamp
student                    
A            NaN          4
B            5.0          6

1
这是适用于我的解决方案 - 输出结构/格式与 last() 相同,但不会覆盖空值。 - YGA
1
这是对我有效的一个 - 输出结构/格式与last()相同,但不会覆盖空值。 - YGA
1
这是对我有效的一个方法 - 输出结构/格式与last()相同,但不会覆盖空值。 - undefined

4
你必须先对数据框进行排序,如果你选择使用 nth 或者 tail。之后你可以删除重复项。
>>> df.sort_values('timestamp').drop_duplicates('student', keep='last')
  student  value_a  timestamp
2       A      NaN          4
1       B      5.0          6

1
无需使用groupby。 :) +1 - Scott Boston
1
不需要分组。:) +1 - Scott Boston
1
不需要分组。:) +1 - undefined
我喜欢!但有点啰嗦。 - YGA
我喜欢!但有点啰嗦。 - YGA
我喜欢!但有点啰嗦。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接