jua*_*man 5 python merge loops dataframe pandas
我有一个初始数据框df1:
df1 = pd.DataFrame(np.array([[1, 'B', 'C', 'D', 'E'], [2, 'B', 'C', 'D', 'E'], [3, 'B', 'C', 'D', 'E'], [4, 'B', 'C', 'D', 'E'], [5, 'B', 'C', 'D', 'E']]), columns=['a', 'b', 'c', 'd', 'e'])
a b c d e
0 1 B C D E
1 2 B C D E
2 3 B C D E
3 4 B C D E
4 5 B C D E
Run Code Online (Sandbox Code Playgroud)
然后,我基于df1列值计算一些新参数,创建一个新df2并在列名“ a”上与df1合并。
df2 = pd.DataFrame(np.array([[1, 'F', 'G'], [2, 'F', 'G']]), columns=['a', 'f', 'g'])
a f g
0 1 F G
1 2 F G
Run Code Online (Sandbox Code Playgroud)
df1 = pd.merge(df1, df2, how='left', left_on=['a'], right_on = ['a'])
a b c d e f g
0 1 B C D E F G
1 2 B C D E F G
2 3 B C D E NaN NaN
3 4 B C D E NaN NaN
4 5 B C D E NaN NaN
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但是在另一个循环事件中,我创建了一个与df2具有相同列的df3,但是在这种情况下合并不起作用,它没有考虑到df1中已经有相同的列。
重要说明:这仅出于说明目的,有数千个新数据帧要添加,每个循环步骤一个。
df3 = pd.DataFrame(np.array([[3, 'F', 'G']]), columns=['a', 'f', 'g'])
a f g
0 3 F G
Run Code Online (Sandbox Code Playgroud)
df1 = pd.merge(df1, df3, how='left', left_on=['a'], right_on = ['a'])
a b c d e f_x g_x f_y g_y
0 1 B C D E F G NaN NaN
1 2 B C D E F G NaN NaN
2 3 B C D E NaN NaN F G
3 4 B C D E NaN NaN NaN NaN
4 5 B C D E NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
我只是使用现有的列来填补缺失的空白。这种方法创建新的列(f_x, g_x, f_y, g_y)。
追加和联系也不起作用,因为它们会重复信息(“ a”上的重复行)。
关于如何解决这个问题的任何建议?最终结果合并后df1用df2,用后df3应为:
a b c d e f g
0 1 B C D E F G
1 2 B C D E F G
2 3 B C D E F G
3 4 B C D E NaN NaN
4 5 B C D E NaN NaN
Run Code Online (Sandbox Code Playgroud)
最终,所有列将在循环期间填充,因此第一个添加的(df2)将添加新的列,从df3开始,仅新数据填充所有NaN。循环如下所示:
df1 = pd.DataFrame(np.array([[1, 'B', 'C', 'D', 'E'], [2, 'B', 'C', 'D', 'E'], [3, 'B', 'C', 'D', 'E'], [4, 'B', 'C', 'D', 'E'], [5, 'B', 'C', 'D', 'E']]), columns=['a', 'b', 'c', 'd', 'e'])
Run Code Online (Sandbox Code Playgroud)
for num, item in enumerate(df1['a']):
#compute df[num] (based on values on df1)
df1 = pd.merge(df1, df[num], how='left', left_on=['a'], right_on = ['a'])
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是concat全部使用小DataFrames,然后仅使用一次merge:
df4 = pd.concat([df2, df3])
print (df4)
a f g
0 1 F G
1 2 F G
0 3 F G
df1 = pd.merge(df1, df4, how='left', on = 'a')
print (df1)
a b c d e f g
0 1 B C D E F G
1 2 B C D E F G
2 3 B C D E F G
3 4 B C D E NaN NaN
4 5 B C D E NaN NaN
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案是DataFrame.combine_first使用DataFrame.set_index:
df1 = (df1.set_index('a')
.combine_first(df2.set_index('a'))
.combine_first(df3.set_index('a')))
print (df1)
b c d e f g
a
1 B C D E F G
2 B C D E F G
3 B C D E F G
4 B C D E NaN NaN
5 B C D E NaN NaN
Run Code Online (Sandbox Code Playgroud)