Python中按行追加DataFrame异常:df.append()合并结果不符预期
解决DataFrame.append()合并多个DataFrame未得到预期结果的问题
嘿,我来帮你排查一下这个问题——用df.append()合并DataFrame没得到预期结果,大概率是踩了这几个常见的坑,咱们一步步来解决:
最常见的问题:append()不会原地修改DataFrame
很多人误以为df_output.append(df_i)会直接把df_i加到df_output里,但其实pandas的append()是返回一个新的DataFrame对象,不会修改原变量。如果你的代码里只写了df_output.append(df_i)而没有重新赋值给df_output,那你的目标DataFrame根本不会有任何变化!
第二个坑:未正确初始化目标DataFrame
如果你的df_output一开始是None或者没定义,第一次执行df_output = df_i.append(df_output)肯定会出问题——比如当df_output是None时,df_i.append(None)的结果完全不是你想要的合并效果。
修复后的append()版本代码
先把df_output初始化为空DataFrame,每次append后重新赋值,记得加上ignore_index=True避免索引重复:
def __merge(self, json_dir_path): if os.path.exists(json_dir_path): # 先筛选出目录下的JSON文件 filelist = [f for f in os.listdir(json_dir_path) if f.endswith('.json')] df_output = pd.DataFrame() # 初始化空的目标DataFrame for f in filelist: json_path = os.path.join(json_dir_path, f) with open(json_path, 'r') as jf: json_data = json.load(jf) csv_path = json_data["accPreparedCSVFileName"] if os.path.exists(csv_path): df_i = pd.read_csv(csv_path) # 关键:把append的返回值重新赋值给df_output df_output = df_output.append(df_i, ignore_index=True) return df_output
更推荐的方案:用pd.concat()替代append()
从pandas 1.4.0开始,append()已经被官方标记为弃用了,而且循环append的效率很低(每次都要创建新对象)。更靠谱的做法是先把所有要合并的DataFrame收集到一个列表里,然后用pd.concat()一次性合并:
def __merge(self, json_dir_path): if not os.path.exists(json_dir_path): return pd.DataFrame() # 目录不存在时返回空DataFrame filelist = [f for f in os.listdir(json_dir_path) if f.endswith('.json')] dfs_to_merge = [] # 用来存放所有读取到的DataFrame for f in filelist: json_path = os.path.join(json_dir_path, f) try: with open(json_path, 'r') as jf: json_data = json.load(jf) csv_path = json_data["accPreparedCSVFileName"] if os.path.exists(csv_path): df_i = pd.read_csv(csv_path) dfs_to_merge.append(df_i) except Exception as e: print(f"处理文件 {f} 时出错: {str(e)}") # 一次性合并所有DataFrame,ignore_index重置索引 df_output = pd.concat(dfs_to_merge, ignore_index=True) return df_output
这种方式不仅性能更好,还能避免append的各种潜在问题,而且代码逻辑更清晰。
额外提醒
- 确保所有要合并的CSV文件列名一致,如果列名不同,
pd.concat()默认会用outer join,缺失的列会填充NaN,你可以根据需求调整join='inner'只保留共同列。 - 加上异常捕获很重要,避免某个JSON或CSV文件读取失败导致整个程序崩溃。
内容的提问来源于stack exchange,提问作者Carlo Allocca
相关产品推荐
相关产品推荐

