如果您有数据框列表
dfs:
dfs = [df1, df2, df3, ... , dfn]
您可以使用panda的
concat功能加入它们,据我所知,此功能比链接合并要快。
concat仅基于索引(而不是列)联接数据框,但是只需进行少量预处理就可以模拟
merge操作。
首先,
dfs用要合并的列替换每个数据框的索引。假设您要在column上合并
"A":
dfs = [df.set_index("A", drop=True) for df in dfs]请注意,这 将 覆盖以前的索引(无论如何合并都将执行此操作),因此您可能希望将这些索引保存在某处(如果出于某种原因以后需要它们)。
现在我们可以使用concat,它实际上将在索引上合并( 实际上是您的列 !)
merged = pd.concat(dfs, axis=1, keys=range(len(dfs)), join='outer', copy=False)
所述
join=参数可以是
'inner'或
'outer'(默认)。该
copy=参数可
concat避免制作不必要的数据框副本。
然后,您可以保留
"A"为索引,也可以通过执行以下操作将其放回列中:
merged.reset_index(drop=False, inplace=True)
该
keys=参数是可选的,并为每个数据帧分配一个键值(在这种情况下,我给了它一个整数范围,但如果需要,可以给它们提供其他标签)。这使您可以访问原始数据帧中的列。因此,如果要获取与第20个数据框相对应的列,
dfs可以调用:
merged[20]
如果不使用该
keys=参数,则可能会混淆哪些行来自哪个数据帧,尤其是当它们具有相同的列名时。
我仍然不确定是否
concat可以线性运行,但绝对比链接快
merge:
在随机生成的数据帧列表(包含10、100和1000个数据帧的列表)上使用ipython的%timeit:
def merge_with_concat(dfs, col): dfs = [df.set_index(col, drop=True) for df in dfs] merged = pd.concat(dfs, axis=1, keys=range(len(dfs)), join='outer', copy=False) return mergeddfs10 = [pd.util.testing.makeDataframe() for i in range(10)] dfs100 = [pd.util.testing.makeDataframe() for i in range(100)] dfs1000 = [pd.util.testing.makeDataframe() for i in range(1000)]%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs10)10 loops, best of 3: 45.8 ms per loop%timeit merge_with_concat(dfs10,"A")100 loops, best of 3: 11.7 ms per loop%timeit merge_with_concat(dfs100,"A")10 loops, best of 3: 139 ms per loop%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs100)1 loop, best of 3: 1.55 s per loop%timeit merge_with_concat(dfs1000,"A")1 loop, best of 3: 9.67 s per loop%timeit reduce(lambda df1, df2: df1.merge(df2, on="A", how='outer'), dfs1000)# I killed it after about 5 minutes so the other one is definitely faster



