如何在Python中通过for循环基于唯一标识符校验两个DataFrame值是否一致?
基于唯一ID校验两个DataFrame的对应值匹配数
数据情况
df1数据:
id|treat ---|--- 123|ice cream 456|cake 789|cookie
df2数据:
id|treat —--|—-- 456|cake 789|cookie 123|cake
需求:通过for循环遍历所有id,校验两个DataFrame中同一id的treat值是否相同,统计匹配的总数量。
现有代码错误分析
第一段代码问题
matches = 0 frames = zip(df1, df2) for x,y, in frames: if x["treats"] == y["treats"]: matches+=1
zip(df1, df2)迭代的是DataFrame的列名(比如'id'、'treat'),不是行数据,因此x和y是列名字符串,无法用x["treats"]取值。- 列名拼写错误:实际列名是
treat,不是treats。 - 循环缩进错误,
for语句前多了不必要的空格。
第二段代码问题
for row in range(len(df1)): idd = df1.iloc[row]['id'] if idd in df2['id'].values: if (df1.iloc[row]['treat']=='cake') and (df2[df2['id'] == idd]['treat'] == 'cake'): matched+= 1
- 变量
matched未初始化,需要先定义matched = 0才能累加。 df2[df2['id'] == idd]['treat']返回的是Series对象,直接和字符串比较会得到布尔Series,不是单个布尔值,需用.iloc[0]或.values[0]取出具体值再比较。- 逻辑局限:仅校验
treat等于'cake'的情况,遗漏了其他值的匹配场景(比如id=789的treat是'cookie'的匹配)。
正确的for循环实现
高效版(推荐)
先把df2转成id到treat的字典,避免每次循环都筛选DataFrame:
matches = 0 # 构建df2的id-treat映射字典 df2_treat_dict = df2.set_index('id')['treat'].to_dict() # 遍历df1的每一行 for _, row in df1.iterrows(): current_id = row['id'] # 检查id是否存在于df2中 if current_id in df2_treat_dict: # 比较两个treat值 if row['treat'] == df2_treat_dict[current_id]: matches += 1 print(f"匹配数量: {matches}")
逐行筛选版(效率较低)
如果坚持用逐行筛选的方式,可修改为:
matches = 0 for row_idx in range(len(df1)): current_id = df1.iloc[row_idx]['id'] # 找到df2中对应id的行 target_row = df2[df2['id'] == current_id] # 确保找到对应行再比较 if not target_row.empty: if df1.iloc[row_idx]['treat'] == target_row['treat'].iloc[0]: matches += 1 print(f"匹配数量: {matches}")
更高效的pandas原生方法(无需for循环)
如果不限制必须用for循环,用pandas合并操作会更简洁高效:
# 按id合并两个DataFrame merged_df = df1.merge(df2, on='id', suffixes=('_df1', '_df2')) # 统计treat值相同的行数 matches = (merged_df['treat_df1'] == merged_df['treat_df2']).sum() print(f"匹配数量: {matches}")
内容的提问来源于stack exchange,提问作者codingrainha
相关产品推荐
相关产品推荐

