我有不同的数据框,需要根据日期列将它们合并在一起。如果我只有两个数据帧,则可以使用df1.merge(df2, on='date')
来处理三个数据帧,而我使用df1.merge(df2.merge(df3, on='date'), on='date')
,但是对多个数据帧进行处理变得非常复杂且难以理解。
所有数据框都有一个共同的列-date
,但它们的行数和列数都不相同,而我只需要每个数据框共有每个日期的那些行。
因此,我正在尝试编写一个递归函数,该函数返回一个包含所有数据的数据框,但是它不起作用。那我应该如何合并多个数据框?
我尝试了不同的方式,并遇到out of range
,keyerror 0/1/2/3
和can not merge DataFrame with instance of type <class 'NoneType'>
之类的错误。
这是我写的脚本:
dfs = [df1, df2, df3] # list of dataframes
def mergefiles(dfs, countfiles, i=0):
if i == (countfiles - 2): # it gets to the second to last and merges it with the last
return
dfm = dfs[i].merge(mergefiles(dfs[i+1], countfiles, i=i+1), on='date')
return dfm
print(mergefiles(dfs, len(dfs)))
一个例子:
df_1:
May 19, 2017;1,200.00;0.1%
May 18, 2017;1,100.00;0.1%
May 17, 2017;1,000.00;0.1%
May 15, 2017;1,901.00;0.1%
df_2:
May 20, 2017;2,200.00;1000000;0.2%
May 18, 2017;2,100.00;1590000;0.2%
May 16, 2017;2,000.00;1230000;0.2%
May 15, 2017;2,902.00;1000000;0.2%
df_3:
May 21, 2017;3,200.00;2000000;0.3%
May 17, 2017;3,100.00;2590000;0.3%
May 16, 2017;3,000.00;2230000;0.3%
May 15, 2017;3,903.00;2000000;0.3%
预期合并结果:
May 15, 2017; 1,901.00;0.1%; 2,902.00;1000000;0.2%; 3,903.00;2000000;0.3%
最佳答案
下面是在不涉及复杂查询的情况下合并多个数据框的最简洁,可理解的方法。
只需简单地将 DATE 作为索引合并,然后使用 OUTER 方法合并(获取所有数据)。
import pandas as pd
from functools import reduce
df1 = pd.read_table('file1.csv', sep=',')
df2 = pd.read_table('file2.csv', sep=',')
df3 = pd.read_table('file3.csv', sep=',')
现在,基本上将您拥有的所有文件作为数据框加载到列表中。然后,使用
merge
或reduce
函数合并文件。# compile the list of dataframes you want to merge
data_frames = [df1, df2, df3]
注意:您可以在上面的列表中添加尽可能多的数据框。 这是有关此方法的好部分。不涉及复杂的查询。
要保留属于同一日期的值,您需要将其合并在
DATE
上df_merged = reduce(lambda left,right: pd.merge(left,right,on=['DATE'],
how='outer'), data_frames)
# if you want to fill the values that don't exist in the lines of merged dataframe simply fill with required strings as
df_merged = reduce(lambda left,right: pd.merge(left,right,on=['DATE'],
how='outer'), data_frames).fillna('void')
然后根据需要将合并的数据写入csv文件。
pd.DataFrame.to_csv(df_merged, 'merged.txt', sep=',', na_rep='.', index=False)
这应该给你
DATE VALUE1 VALUE2 VALUE3 ....