You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas循环处理小DataFrame正常,大数据集卡顿如何优化?

哇,7万条数据用iterrows()跑40小时,这确实太折磨人了!我来帮你把速度提上去,顺便聊聊哈希的问题~


问题根源:为什么你的代码这么慢?

  • 你用了iterrows()逐行遍历,这是Pandas里效率最低的操作之一——它是Python级别的循环,每次迭代都有额外的开销。
  • 更糟的是,每处理一个邮编,你都要完整遍历一遍邮编表zc,时间复杂度直接拉到O(n*m)(n是你的7万条数据,m是邮编表的行数),这就是为什么预估时间会超40小时。

最优提速方案:用Pandas的merge做矢量化匹配

Pandas的merge是底层用C实现的矢量化操作,专门处理这类表连接场景,速度能提升几个数量级。针对你提到的三种邮编类型(有效数字、非数字字符串、无效数字字符串),我们可以这样处理:

步骤1:预处理两个表的邮编字段

先统一字段类型,避免匹配时的类型冲突:

import numpy as np
import pandas as pd

# 加载数据
df = pd.read_csv('customer_April2018.csv', encoding='latin-1')
zc = pd.read_csv('us_postal_codes.csv', encoding='latin-1')

# 把邮编表的ZipCode转成数值类型(方便和用户表的邮编匹配)
zc['ZipCode_num'] = zc['ZipCode'].astype(int)

# 处理用户表的邮编:能转成数字的转成数值,不能转的设为NaN
df['ZipCode_clean'] = pd.to_numeric(df['ZipCode'], errors='coerce')

步骤2:用merge批量匹配县份

这一步会一次性完成所有匹配,完全替代低效的循环:

# 左连接:保留用户表所有行,匹配到的填充County,没匹配到的留空
df_merged = df.merge(
    zc[['ZipCode_num', 'County']],
    left_on='ZipCode_clean',
    right_on='ZipCode_num',
    how='left'
)

# 把没匹配到的情况(包括非数字、无效数字邮编)统一设为'No County'
df_merged['County'] = df_merged['County'].fillna('No County')

# 清理临时字段并保存结果
df_merged.drop(columns=['ZipCode_clean', 'ZipCode_num'], inplace=True)
df_merged.to_csv('join_test.csv', index=False)

关于哈希函数的疑问:你不需要自己实现!

其实Pandas的merge在默认情况下(当连接字段是数值/字符串时),已经使用了哈希连接的优化策略——它会先对连接字段构建哈希表,然后一次性完成匹配,这正是处理大规模数据的最优方案。自己手动实现哈希函数不仅没必要,还可能因为优化不到位反而变慢,直接用Pandas内置的merge就够了。

额外小提示:如果邮编带前导零

如果你的有效邮编包含前导零(比如'00123'),转成数值会丢失前导零,这时候应该把两个表的邮编都转成字符串来匹配:

# 统一转成5位字符串,保留前导零
zc['ZipCode_str'] = zc['ZipCode'].astype(str).str.zfill(5)
df['ZipCode_str'] = df['ZipCode'].str.zfill(5)

# 用字符串做连接匹配
df_merged = df.merge(
    zc[['ZipCode_str', 'County']],
    left_on='ZipCode_str',
    right_on='ZipCode_str',
    how='left'
)

这样处理完,7万条数据应该在几秒到几十秒内就能完成,完全不用等40小时啦!

内容的提问来源于stack exchange,提问作者user40551

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:30:29