如何合并索引重叠、列不同的Pandas DataFrame?
合并多CSV文件生成全时间窗口DataFrame的正确方法
问题背景
有大量CSV文件需要读入Python并按规则合并,文件特征:
- 索引为时间维度
- 列代表特定实体
- 不同文件的索引可能重叠,但索引值一致
- 文件列数不一定相同
最终要生成包含全时间窗口、所有实体的大型DataFrame,示例如下:
import pandas as pd import numpy as np df_1 = pd.DataFrame(data=[[np.nan, 2],[np.nan, 4],[np.nan, 8]],index = [0,1,2],columns=["A","B"]) df_2 = pd.DataFrame(data=[[4, 8, 2],[4, 2, 8],[6, 1, 1]],index = [2,3,4],columns=["A","B","C"]) df_3 = pd.DataFrame(data=[[2, np.nan, 4],[8, np.nan, 8],[1, 8, 10]],index = [2,3,4],columns=["C","D","E"]) # 预期结果 df_end = pd.DataFrame(data=[[np.nan, 2, np.nan, np.nan, np.nan], [np.nan, 4, np.nan, np.nan, np.nan], [4, 8, 2, np.nan, 4], [4, 2, 8, np.nan, 8], [6, 1, 1, 8, 10]], index = [0, 1, 2, 3, 4], columns=["A","B","C","D","E"])
错误尝试分析
以下代码无法得到预期结果:
temp = pd.concat([df_1,df_2,df_3]) temp[~temp.index.duplicated(keep="first")]
原因是pd.concat默认按行堆叠(axis=0),会把所有行拼接在一起,此时重复索引的行是独立条目;之后去重保留第一行,会直接丢弃后续文件中同索引的行,丢失大量列和有效数据。
正确解法
方法1:按索引分组取最后有效值
先按行拼接所有DataFrame,再以索引为分组依据取每组最后一行——既能保留全量时间索引,又能自动合并所有列;对于同索引同列的情况,后续文件的非空值会覆盖前面的空值,完全匹配示例需求:
# 实际场景中可通过循环批量读取CSV文件,此处用示例DataFrame列表 dfs = [df_1, df_2, df_3] # 拼接后按索引分组取最后一行 df_final = pd.concat(dfs).groupby(level=0).last() # 可选:按指定顺序排列列(若需和预期结果列序完全一致) df_final = df_final[["A","B","C","D","E"]]
方法2:链式使用combine_first
如果文件数量不多,可依次用combine_first合并,该方法会自动对齐索引和列,用后续DataFrame的非空值填充前面的空值:
df_final = df_1.combine_first(df_2).combine_first(df_3)
两种方法都能生成与df_end一致的结果,其中方法1更适合处理大量文件的场景。
内容的提问来源于stack exchange,提问作者swissy
相关产品推荐
相关产品推荐

