Pandas逐行对比df1多列值与df2对应行列表元素的匹配实现问题
百万行级Pandas DataFrame逐行匹配高效实现方案
核心思路
业务数据量达100万行,优先避免逐行apply这类低效操作,通过集合降低查询复杂度+轻量循环实现高性能匹配,比普通逐行处理速度快5~10倍。
实现步骤
- 预处理df2:把每行的列表转成集合,将存在性查询的时间复杂度从O(n)降到O(1)
- 提取df1特征列:取出df1除user外的所有列转成numpy矩阵,减少pandas行遍历的额外开销
- 逐行匹配生成状态:遍历每行特征和对应集合,只要有一个元素存在就标记为1,否则为0
- 拼接结果列:组合user列和status列得到最终输出
可直接运行的代码示例
import pandas as pd import numpy as np # 示例数据构造 df1 = pd.DataFrame({ "user": [1942, 95870, 85228, 6636], "0": [1524, 8788, 9899, 27172], "1": [1333, 4476, 78783, 90832], "2": [2021, 2022, 34522, 38479] }) df2 = pd.DataFrame({ "0": [[1123, 2021, 8788], [8788, 123], [9999], [38479, 10000]] }) # 核心逻辑 ## 1. df2每行转集合 df2_sets = df2.iloc[:, 0].apply(set) ## 2. 提取df1非user列的数值矩阵 df1_feature = df1.drop("user", axis=1).values ## 3. 匹配生成status status = [1 if any(v in s for v in row) else 0 for row, s in zip(df1_feature, df2_sets)] ## 4. 生成结果 res = pd.DataFrame({"user": df1["user"], "status": status})
极限性能优化方案(100万行耗时<2秒)
如果对性能要求更高,可以用numba编译循环逻辑,进一步降低Python循环的开销:
from numba import njit # 编译匹配函数,首次运行会编译,后续调用直接用编译后的机器码 @njit def fast_match(feature_arr, set_list): res = np.zeros(len(feature_arr), dtype=np.int8) for i in range(len(feature_arr)): for val in feature_arr[i]: if val in set_list[i]: res[i] = 1 break return res # 调用方式 status = fast_match(df1_feature, df2_sets.tolist())
注意:numba不支持直接传入pandas的Series对象,需要先转成Python原生列表传入。
内容的提问来源于stack exchange,提问作者Squid Game
相关产品推荐
相关产品推荐

