如何将多DataFrame的多列传入函数并实现指定数据匹配需求
问题
需要将多个DataFrame的多列传入自定义函数,实现以下需求:
- 找出Df2的E列中未出现在Df1的C列(C列含逗号分隔值)的内容
- 拼接Df1的A、B列生成
A_B格式的结果
当前遇到的问题:
- 单独传入单个字符串参数时函数输出正确,但直接传入DataFrame列(Series对象)时行为异常
- 无法过滤Df1中C列的nan值
示例数据
Df1:
| A | B | C |
|---|---|---|
| 1 | 11 | 111,333 |
| 2 | 22 | 222 |
| 3 | 33 | nan |
Df2:
| D | E |
|---|---|
| a | 111 |
| b | 333 |
期望输出
| newcol | C |
|---|---|
| 2_22 | 222 |
自定义函数及调用代码
import pandas as pd def get_wrong_ls(a,b,c,d): wrong_l_list = [] wrong_l_dict = {} if c is not None: c_list = str(c).split(",") for ele in c_list: if ele not in d: wrong_l_dict[str(a)+"_"+str(b)] = c wrong_l_list.append(wrong_l_dict) return pd.DataFrame(wrong_l_list) # 调用方式 fd = get_wrong_ls(df1['A'],df1['B'],df1['C'],df2['E'])
解决方案
原函数的核心问题
- nan判断错误:
c is not None无法识别pandas的nan,需要用pd.notna()来判断非空值 - 参数类型不匹配:直接传入Series时,函数逻辑是针对单个值设计的,没有处理批量数据的逻辑
- 查找效率低:直接用
ele not in d(d是Series)会遍历整个Series,转成集合能大幅提升查找速度 - 结果构建逻辑冗余:循环中重复添加同一个字典到列表,会产生多余的重复数据
修正后的代码
import pandas as pd # 先把Df2的E列转成字符串集合,优化查找效率 df2_e_set = set(df2['E'].astype(str)) def process_row(row): a, b, c = row['A'], row['B'], row['C'] # 过滤nan值 if pd.notna(c): c_list = str(c).split(",") # 检查C列拆分后的所有元素是否都不在Df2的E列中 if all(ele not in df2_e_set for ele in c_list): return pd.Series({'newcol': f"{a}_{b}", 'C': c}) # 不符合条件则返回空值 return pd.Series({'newcol': None, 'C': None}) # 逐行处理Df1,过滤掉空值行 result = df1.apply(process_row, axis=1).dropna(subset=['newcol', 'C']).reset_index(drop=True) print(result)
代码说明
- 预处理Df2的E列:转成字符串集合
df2_e_set,后续查找操作的时间复杂度从O(n)降到O(1) - 逐行处理Df1:用
apply(axis=1)遍历Df1的每一行,确保函数处理单个行数据,匹配原函数的单值逻辑 - 正确过滤nan:用
pd.notna(c)判断C列是否为有效非空值 - 结果判断逻辑:用
all()检查C列拆分后的所有元素都不在Df2的E列中,符合条件才生成结果 - 整理结果:用
dropna()过滤掉不符合条件的空行,reset_index()重置索引
运行结果
newcol C 0 2_22 222
内容的提问来源于stack exchange,提问作者Megha_991
相关产品推荐
相关产品推荐

