查找同一份CSV导出导入前后两个pandas DataFrame的差异值
问题根源
你遇到的不一致核心原因是CSV为纯文本序列化格式,无法保留Python原生对象类型:原DataFrame中存储的list对象导出到CSV时会被强制转为字符串形式(比如原[1,2,3]存到CSV中会变成文本"[1, 2, 3]",读回后是str类型而非原list类型,equals方法自然返回False。而isin判断失效也是因为类型不匹配导致值比对失败,因此筛选不出差异结果。
定位具体差异的步骤
1. 先排查列类型差异
这是最常见的诱因,先逐列比对两个DataFrame的字段类型:
dtype_diff = [] for col in df_final.columns: if df_final[col].dtype != df_final_csv[col].dtype: dtype_diff.append((col, df_final[col].dtype, df_final_csv[col].dtype)) print("类型不一致的列:", dtype_diff)
正常情况下你会看到存储list的列,原类型为object,读回后虽然仍显示object但实际元素已经是字符串类型。
2. 逐单元格定位具体差异
如果类型排查后仍未明确问题,可以用遍历的方式逐单元格比对,不受对象类型限制:
diff_positions = [] for row in range(df_final.shape[0]): for col in range(df_final.shape[1]): val_orig = df_final.iloc[row, col] val_csv = df_final_csv.iloc[row, col] if val_orig != val_csv: col_name = df_final.columns[col] diff_positions.append({ "行号": row, "列名": col_name, "原数值": val_orig, "原类型": type(val_orig), "读取后数值": val_csv, "读取后类型": type(val_csv) }) # 输出前10个差异点 print("差异点总数:", len(diff_positions)) for d in diff_positions[:10]: print(d)
修复一致性问题的方案
方案1:坚持用CSV格式的适配方法
读取CSV后把字符串格式的列表转回原生list即可:
import ast # 遍历所有列做格式转换 for col in df_final_csv.columns: try: df_final_csv[col] = df_final_csv[col].apply(ast.literal_eval) except (ValueError, SyntaxError): # 非可转换的普通字符串列直接跳过 continue # 二次验证 print(df_final.equals(df_final_csv))
方案2:更稳妥的原生序列化方案
如果没有强制要求用CSV,推荐用pandas原生pickle格式,可100%保留所有Python对象类型,不会出现类型丢失:
# 导出 df_final.to_pickle('integrated_df.pkl') # 读取 df_final_pkl = pd.read_pickle('integrated_df.pkl') print(df_final.equals(df_final_pkl)) # 返回True
内容的提问来源于stack exchange,提问作者Tim Kirkwood
相关产品推荐
相关产品推荐

