使用groupby有效地对大型数据帧进行Fillna(向前填充)?

时间:2016-04-26 17:27:08

标签: pandas

在大型数据框中转发填充信息的最有效方法是什么?

我从日常文件中合并了大约600万行x 50列的维度数据。我删除了重复项,现在我有大约200,000行唯一数据,可以跟踪其中一个维度发生的任何变化。

不幸的是,一些原始数据混乱并且具有空值。如何使用以前的值有效填充空数据?

id       start_date   end_date    is_current  location  dimensions...
xyz987   2016-03-11   2016-04-02  Expired       CA      lots_of_stuff
xyz987   2016-04-03   2016-04-21  Expired       NaN     lots_of_stuff
xyz987   2016-04-22          NaN  Current       CA      lots_of_stuff

这是数据的基本形状。问题是某些维度不应该是空白的(这是原始数据中的错误)。例如,对于前一行,该行的位置已填写,但在下一行中为空白。我知道该位置没有改变,但它将其捕获为一个唯一的行,因为它是空白的。

我假设我需要使用ID字段进行分组。这是正确的语法吗?我是否需要列出数据框中的所有列?

cols = [list of all of the columns in the dataframe]
wfm.groupby(['id'])[cols].fillna(method='ffill', inplace=True)

200,000行数据框中有大约75,000个唯一ID。我试过做

df.fillna(method='ffill', inplace=True)

但我需要根据ID进行操作,并且我希望确保尽可能高效(我的计算机需要很长时间才能读取并将所有这些文件合并到内存中)。

3 个答案:

答案 0 :(得分:3)

如何向前填补每个小组?

 df = df.groupby(['id'], as_index=False).apply(lambda group: group.ffill())

答案 1 :(得分:2)

直接在groupby对象上执行fillna可能很有效:

df = df.groupby(['id']).fillna(method='ffill')

引用的方法 here 在文档中。

答案 2 :(得分:2)

github / jreback:这是#7895的骗局。 .ffill没有在groupby操作的cython中实现(虽然它当然可以),而是在每个组上调用python空间。 这是一个简单的方法。 网址:https://github.com/pandas-dev/pandas/issues/11296

根据jreback的回答,当你做一个groupby时ffill()没有优化,但是cumsum()是。试试这个:

df = df.sort_values('id')
df.ffill() * (1 - df.isnull().astype(int)).groupby('id').cumsum().applymap(lambda x: None if x == 0 else 1)