超大型DataFrame高效执行groupby与bfill的方法求助
问题描述
我有一个包含2768186062行的DataFrame,数据示例如下:
email email_created_date country a01423240@itesm.mx 2021-03-27 00:44:49+00:00 NaN a01423240@itesm.mx 2022-01-14 16:27:18+00:00 IND aalvarezleo@gmail.com 2021-05-14 13:24:15+00:00 NaN aalvarezleo@gmail.com 2021-09-16 16:09:45+00:00 IND acabazot@gmail.com 2021-03-27 00:38:37+00:00 NaN acabazot@gmail.com 2022-01-14 12:25:28+00:00 IND alt_wwe@hotmail.com 2022-09-22 22:08:50+00:00 NaN alt_wwe@hotmail.com 2022-09-22 22:11:51+00:00 CA
需求:按email分组,对country列执行反向填充(bfill),预期输出如下:
email email_created_date country a01423240@itesm.mx 2021-03-27 00:44:49+00:00 IND a01423240@itesm.mx 2022-01-14 16:27:18+00:00 IND aalvarezleo@gmail.com 2021-05-14 13:24:15+00:00 IND aalvarezleo@gmail.com 2021-09-16 16:09:45+00:00 IND acabazot@gmail.com 2021-03-27 00:38:37+00:00 IND acabazot@gmail.com 2022-01-14 12:25:28+00:00 IND alt_wwe@hotmail.com 2022-09-22 22:08:50+00:00 CA alt_wwe@hotmail.com 2022-09-22 22:11:51+00:00 CA
我用以下代码实现,但因数据量过大,执行时间已超1小时:
dt1[['country']]=(dt1 .sort_values(['email','email_created_date']) .groupby(['email'], as_index=False)[['country']].fillna(method='bfill'))
需要更高效的实现方法,最大化处理效率。
高效解决方案
方法1:使用groupby.transform替代分组后fillna
groupby.transform直接对分组列应用bfill,避免额外的数据复制与索引操作,性能远优于原方法:
# 先确保数据按email和创建日期排序 dt1 = dt1.sort_values(['email', 'email_created_date']) # 分组后用transform执行bfill dt1['country'] = dt1.groupby('email')['country'].transform(lambda x: x.bfill())
方法2:利用email对应最终country值映射(针对你的数据特征)
从示例可见,每个email的最后一行country均为非空值,这种场景下可直接提取每组最终country值做映射填充,是效率最高的方案:
# 按email分组,提取每组最后一个非空的country值 email_country_map = dt1.sort_values(['email', 'email_created_date'])\ .groupby('email')['country'].last() # 通过映射直接填充country列 dt1['country'] = dt1['email'].map(email_country_map)
该方法跳过逐行bfill操作,用字典映射完成填充,时间复杂度接近O(n),对超大规模数据的效率提升极为显著。
额外优化建议
- 确保
email列为字符串类型,避免分组时的类型转换开销 - 若内存允许,将
email列转为分类类型(dt1['email'] = dt1['email'].astype('category')),可大幅降低分组操作的内存占用与时间消耗 - 使用pandas 2.0+版本时,启用
pyarrow后端(设置pd.set_option('mode.copy_on_write', True)或使用pyarrow数据类型),可进一步提升大数据处理性能
内容的提问来源于stack exchange,提问作者nikki
相关产品推荐
相关产品推荐

