Pandas报错ValueError: Columns must be same length as key解决方法
报错根因
执行df1[["f2_research_groups_names", "f2_location"]] = df1.apply(fn, axis=1)触发该错误的核心原因是:自定义函数fn逐行返回的结果长度,和等号左侧待赋值的列数(固定为2)不匹配,结合你的业务场景,通常是三类问题导致:
- 匹配成功时直接返回df2的整行对象,若df2除了机构名、属地外存在其他列,返回的Series长度大于2
- 匹配失败时返回
None、空值,返回结果长度为0 - 存在一个原名匹配到多个标准名的情况,返回了多行结构,长度远超2
修正方案
不要在逐行apply逻辑里重复遍历整个df2(数据量大时性能极差),提前把标准映射关系预处理为字典,同时保证fn所有返回分支的结果长度固定为2,从根源上对齐列长度要求。
完整可运行代码如下:
import pandas as pd import numpy as np # 读取两份源文件 df1 = pd.read_csv("file1.csv") df2 = pd.read_csv("file2.csv") # 按规则给列名加前缀 df1 = df1.add_prefix("f1_") df2 = df2.add_prefix("f2_") # 预处理映射关系,避免逐行apply时重复遍历df2 std_name_list = df2["f2_research_groups_names"].str.strip().tolist() std_name2loc = df2.set_index("f2_research_groups_names")["f2_location"].to_dict() def match_organization(row): raw_name = str(row["f1_research_groups_names"]).strip() # 优先精确匹配 if raw_name in std_name2loc: return pd.Series([raw_name, std_name2loc[raw_name]]) # 精确匹配失败走包含匹配 for std_name in std_name_list: if std_name in raw_name or raw_name in std_name: return pd.Series([std_name, std_name2loc[std_name]]) # 无匹配结果时返回固定长度的空值,保证列对齐 return pd.Series([np.nan, np.nan]) # 执行多列赋值 df1[["f2_research_groups_names", "f2_location"]] = df1.apply(match_organization, axis=1) # 导出要求的三列结果,用utf-8-sig编码避免Excel打开中文乱码 output_columns = ["f1_research_groups_names", "f2_research_groups_names", "f2_location"] df1[output_columns].to_csv("Output.csv", index=False, encoding="utf-8-sig")
注意事项
- 预处理映射字典的写法比逐行遍历df2的写法性能高10~100倍,数据量越大差距越明显
- 只要保证apply传入的函数所有返回分支的序列长度和待赋值列数一致,就不会再触发同类长度不匹配报错
- 无匹配的行会自动留空,不会中断整体运行流程
- 如果需要调整匹配规则(比如加模糊匹配权重、处理别名),直接修改
match_organization函数内的判断逻辑即可
内容的提问来源于stack exchange,提问作者DaviComputerVision
相关产品推荐
相关产品推荐

