Pandas Merge不符合预期:如何实现目标输出结果?
解决Pandas合并后出现重复行的问题
问题原因
你当前的代码分别对A2、A3系列列做melt转换后,仅通过Q1字段合并,这会触发笛卡尔积匹配——每个Q1对应的所有A2值会和所有A3值逐一配对,自然产生大量重复行。而你需要的是A2_1对应A3_1、A2_2对应A3_2这种同序号的一一匹配关系,所以需要额外的匹配键来约束合并逻辑。
解决方案
方法1:提取序号作为额外匹配键
通过拆分列名提取序号后缀,将其作为合并时的第二个匹配键,确保同序号的A2和A3值对应:
import pandas as pd data = { "Q1": [1, 2, 3, 4], "A2_1": [1, 2, 2, 1], "A2_2": [1, 1, 1, 1], "A2_3": [2, 2, 1, 1], "A2_4": [2, 2, 2, 1], "A3_1": [10, 25, 62, 18], "A3_2": [51, 51, 16, 17], "A3_3": [32, 23, 71, 31], "A3_4": [62, 52, 52, 11] } df = pd.DataFrame(data) # 处理A2列,提取序号后缀 melted_a2 = pd.melt(df, id_vars=["Q1"], value_vars=["A2_1", "A2_2", "A2_3", "A2_4"], var_name="A2", value_name="A2_Value") melted_a2["idx"] = melted_a2["A2"].str.split("_").str[-1] # 处理A3列,提取序号后缀 melted_a3 = pd.melt(df, id_vars=["Q1"], value_vars=["A3_1", "A3_2", "A3_3", "A3_4"], var_name="A3", value_name="A3_Value") melted_a3["idx"] = melted_a3["A3"].str.split("_").str[-1] # 按Q1和序号合并,确保同序号的A2、A3值对应 result_df = pd.merge(melted_a2, melted_a3, on=["Q1", "idx"]) # 清理冗余列 result_df = result_df.drop(columns=["A2", "A3", "idx"]) print(result_df)
方法2:使用wide_to_long直接转换(更简洁)
Pandas的wide_to_long函数专门针对这种带有序号后缀的宽表设计,能直接完成同序号列的配对转换,无需手动拆分和合并:
import pandas as pd data = { "Q1": [1, 2, 3, 4], "A2_1": [1, 2, 2, 1], "A2_2": [1, 1, 1, 1], "A2_3": [2, 2, 1, 1], "A2_4": [2, 2, 2, 1], "A3_1": [10, 25, 62, 18], "A3_2": [51, 51, 16, 17], "A3_3": [32, 23, 71, 31], "A3_4": [62, 52, 52, 11] } df = pd.DataFrame(data) # 直接转换宽表,指定前缀(A2/A3)、索引(Q1)、序号后缀规则 result_df = pd.wide_to_long(df, stubnames=["A2", "A3"], i="Q1", j="idx", sep="_", suffix=r"\d+") # 重置索引(可选,根据是否需要保留序号列调整) result_df = result_df.reset_index() # 移除序号列(如果不需要的话) result_df = result_df.drop(columns=["idx"]) print(result_df)
两种方法最终都会输出符合预期的结果:每个Q1对应4行,每行是同序号的A2和A3值的一一匹配,无重复行。
内容的提问来源于stack exchange,提问作者Denis Navotny
相关产品推荐
相关产品推荐

