python - 使用 Pandas 将 Dataframe 折叠为每组一行
问题描述
我有一个如下所示的数据框:
id A B date
a 1 NAN 2016-01-01
a NAN 6 2016-01-02
a 7 NAN 2016-10-01
b 3 5 2016-12-01
我想按日期和 id 折叠(每个组进入一行,使用组中最后一个日期的数据,并用组中的最新数据填充缺失的数据)。groupby 大致如下所示:
df.groupby(['id', pd.Grouper(key='date', freq='30D')])
这将导致像这样的数据框:
id A B date
a 1 6 2016-01-02
a 7 NAN 2016-10-01
b 3 5 2016-12-01
一个非常简单的例子。我相信我的 groupby 会起作用,但我不确定如何将行组合成一行,并使用每列中的最新数据聚合数据,如有必要,转发填充数据(如果它们都是 NAN,只需使用一个南)。
解决方案
df.groupby(['id', pd.Grouper(key='date', freq='30D')]).apply(lambda g: g[["A", "B"]].ffill().iloc[-1])
结果:
A B
id date
a 2016-01-01 1 6.0
2016-09-27 7 NaN
b 2016-11-26 3 5.0
编辑:为了解决您的评论,如果您想避免使用apply
,您也可以使用两个groupby
s:
groupers = ['id', pd.Grouper(key='date', freq='30D')]
df.groupby(groupers).ffill().groupby(groupers).last()
结果:
A B
id date
a 2016-01-01 1 6
2016-09-27 7 NaN
b 2016-11-26 3 5
看起来性能类似于apply
:
In [1]: groupers = ['id', pd.Grouper(key='date', freq='30D')]
In [2]: %%timeit
...: df.groupby(groupers).ffill().groupby(groupers).last()
...:
100 loops, best of 3: 9.79 ms per loop
In [3]: %%timeit
...: df.groupby(groupers).apply(lambda g: g[["A", "B"]].ffill().iloc[-1])
...:
100 loops, best of 3: 10.5 ms per loop
推荐阅读
- swiftui - 使用 swiftUI 语言在应用启动时获取推送通知详细信息
- javascript - 随着屏幕宽度的变化缩小和扩大表格宽度
- line - 如果我们给出上一行中的单词,如何打印下一行
- sql - 查询根据关系和约束更新记录计数
- node.js - 从路由 nodejs 将变量发送到 js 文件
- three.js - 是否可以在threejs编辑器中重用材料
- java - 如何实时更新 TextArea 的输入?
- angular - 访问 mat-row Angular Material Table 中的组件实例
- java - 使用对象输入流。当我使用 readObject() 方法时,它给了我一个名为 EOFException 的异常
- r - 在 R markdown notebook 中打印或保留每次循环运行的输出