【发布时间】:2017-12-20 23:59:22
【问题描述】:
我有一个 Pandas 数据框。我使用groupBy(在 1 列上)+apply 组合向数据框添加新列。 apply 调用带有参数的自定义函数。完整的调用如下所示:
df = df.groupby('id').apply(lambda x: customFunction(x,'searchString'))
自定义函数的工作方式如下:基于ifelse 条件,新列填充1 或0。然后返回该组。有点笼统,自定义函数长这样:
def customFunction(group,searchString):
#print(group.iloc[[0]]['id'].values[0])
if len(group[(group['name'] == searchString)) > 0:
group['newColumn'] = 1
else:
group['newColumn'] = 0
return group
我的问题是脚本运行时间相对较长,尽管我并没有处理太多数据。这些是我的数据统计: 数据框有 3130 行和 49 列。 groupBy 生成 1499 个单独的组。
如果我在customFunction 中输出一些调试文本,我观察到每个组的实际迭代相当快,但是在最后需要更多秒(比迭代本身更长)直到groupBy实际上已经完成。我认为这与重新索引或重新分配新列中的新数据有关。
我现在的问题是:
- 为什么
groupBy+apply需要这么长时间?为什么实际迭代已经完成的部分,需要这么长时间? - 如何避免这个瓶颈?如何改进我的代码(见上文)以更快地执行?
- 更一般地说:如何最有效地实现“按特定列分组,然后根据条件添加新列”模式?也许一种方法是创建一个单独的数据结构而不需要返回组。然后,在一个单独的步骤中,新计算的数据结构可以与原始数据帧连接。但是,我不太确定这是否真的会表现得更好。
应该避免读取返回组,因为它需要很长时间,但我认为在我的情况下这是必要的,因为我在customFunction 中明确生成了新数据,这需要返回数据。
【问题讨论】:
-
请发布示例数据
-
在应用函数之前尝试聚合组:
df.groupby('id').sum().apply(...) -
这需要很长时间,因为对于每一行,您都会调用自定义函数。你想做什么?应该可以使用更快的技术。
-
@cᴏʟᴅsᴘᴇᴇᴅ,不,在这种情况下,将为每个组调用一次自定义函数(第一组除外 - Pandas makes one extra call for the first group (see Notes))
标签: python performance pandas group-by apply