Python Pandas-基于多个匹配列值更新/合并2个数据帧
我有两个数据帧Python Pandas-基于多个匹配列值更新/合并2个数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,我有两个数据帧left_-df和right-df,它们都有20个列,具有相同的名称和数据类型right_df还有两个附加列,每行上都有唯一的值 我想用left_df中的所有值更新right_df中的行,其中列子集列表中所有列中的值,matching_cols=['col_1','col_3','col_10','col u 12']在两个数据帧中都是相同的。应保留right_df中另外两个唯一列中的值 理想情况下,我还希望在同一个命令中从left_df删除这些行,如果不可能,则作为下一个命令。我
left_-df
和right-df
,它们都有20个列,具有相同的名称和数据类型right_df
还有两个附加列,每行上都有唯一的值
我想用left_df
中的所有值更新right_df
中的行,其中列子集列表中所有列中的值,matching_cols=['col_1','col_3','col_10','col u 12']
在两个数据帧中都是相同的。应保留right_df
中另外两个唯一列中的值
理想情况下,我还希望在同一个命令中从left_df
删除这些行,如果不可能,则作为下一个命令。我需要不止一次地执行这个过程,在几个不同的列列表上进行匹配,使用left_df
在每个循环中删除匹配的行,直到最终找不到进一步的匹配
一种可接受的替代方法是创建一个新的数据框new_df
,其中包含列表中所有指定列匹配的行集matching_cols
,前20列中的值来自left_df
,其余2列中的值来自right_df
我不关心在任何一个数据帧中的任何一点上保留索引,我将在这之后将它们导入SQL,并将在最后的2个right_df
值之一上重新为它们编制索引
Pandas新手,无法确定使用哪种方法,尝试了.merge
、.join
、.update
等变体,但似乎无法指定仅在所需列值全部匹配时更新,或如何删除这些行/将其导出到新的df
更新:在下面添加了伪代码:
对于left_df
as:
left_df = pd.DataFrame({
'col_0': ['0', '1', '2', '3', '4', '5'],
'col_1': ['A', 'B', 'C', 'D', 'E', 'F'],
'col_2': ['new', 'new', 'new', 'new', 'new', 'new'],
'col_3': ['new', 'new', 'new', 'new', 'new', 'new'],
'col_4': ['new', 'new', 'new', 'new', 'new', 'new'],
'col_5': ['new', 'new', 'new', 'new', 'new', 'new'],
'col_6': ['new', 'new', 'new', 'new', 'new', 'new'],
'col_7': ['new', 'new', 'new', 'new', 'new', 'new'],
})
和一个右_df,如下所示:
right_df = pd.DataFrame({
'col_0': ['0', '1', '2', '3', '4', '5'],
'col_1': ['A', 'B', 'C', 'X', 'E', 'F'],
'col_2': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_3': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_4': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_5': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_6': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_7': ['old', 'old', 'old', 'old', 'old', 'old'],
'col_8': ['uid_0', 'uid_1', 'uid_2', 'uid_3', 'uid_4', 'uid_5'],
'col_9': ['uid_a', 'uid_b', 'uid_c', 'uid_d', 'uid_e', 'uid_f'],
})
其中匹配列=['col\u 0','col\u 1']
我想得到以下结果,要么作为新的数据帧,要么在右侧_df
上得到(请注意,列1
在第3行不匹配,因此没有更改)
试试这个
new_df=pd.concat([left_df,right_df.iloc[:,-1:-3]],axis=1)
感谢Pandas和文档:
首先,我需要一个.merge
,我将后缀指定为“\r'
,仅用于从右侧复制的列,用于我正在更新的旧值:
merged_df = pd.merge(left_df, right_df, on=['col_0', 'col_1'], suffixes=(None, '_r'))
这将生成一个新的数据帧,其中的行同时包含新列和旧列,仅适用于每个数据帧中列on=['col\u 0','col\u 1']
中的值匹配的行。然后在文本“\u r”
上使用正则表达式过滤器删除“old”列:
merged_df.drop(list(merged_df.filter(regex = '_r')), axis=1, inplace=True)
这将生成一个数据帧,其中只有“修改的”行,没有未修改的行,这足以满足我的需要
col_0 col_1 col_2 col_3 col_4 col_5 col_6 col_7 col_8 col_9
0 0 A new new new new new new uid_0 uid_a
1 1 B new new new new new new uid_1 uid_b
2 2 C new new new new new new uid_2 uid_c
3 4 E new new new new new new uid_4 uid_e
4 5 F new new new new new new uid_5 uid_f
在这里,.iloc[:,-1:-3]
指的是什么?更新:尝试过了,它可以工作,但是它忽略了我需要从右(右)df
中包含在结果中的两列。.iloc[:,-1:-3]
是对数据帧中的列进行索引,如果你需要特定的列,你也可以尝试.loc:,['以逗号分隔的列列表']
这肯定会解决我刚才看到的所有问题,我认为上面的答案将起作用(.loc)
因为这是我可能想到的唯一正确的方法来压缩数据,``你必须在loc中正确地指定名称,``请尝试在数据new_df=pd.concat([left_df,right_df.loc[:,[col_0','col_1','col_8','col u 9',axis=1]中删除两次出现的
col_0 col_1 col_2 col_3 col_4 col_5 col_6 col_7 col_8 col_9
0 0 A new new new new new new uid_0 uid_a
1 1 B new new new new new new uid_1 uid_b
2 2 C new new new new new new uid_2 uid_c
3 4 E new new new new new new uid_4 uid_e
4 5 F new new new new new new uid_5 uid_f