Pandas 强制对包含重复键的列进行一对一合并

我有两个Dataframes,df1:


| ID        | Invoice   |

-------------------------

| X\191     | 4         |

| R\192     | 4         |

| 733       | 1         |

| X215      | 3         |

| BL000002  | 3         |

df2:


| ID        | Invoice   |

-------------------------

| X191      | 4         |

| X215      | 3         |

| BL000002  | 3         |

我应该将它们一一合并以获得:


| ID        | Invoice   | ID        |

-------------------------------------

| X\191     | 4         | X191      |

| X\192     | 4         |           |

| 733       | 1         |           |

| X215      | 3         | X215      |

| BL000002  | 3         | BL000002  |

但是当我进行外部合并时,我会得到重复的值


import pandas as pd

dict1 = {"ID": ["X\\191","R\\192","733","X215","BL000002"], "Inv": [4,4,1,3,3]}

df1 = pd.DataFrame.from_dict(dict1)


dict2 = {"ID": ["X191","X215","BL000002"], "Inv": [4,3,3]}

df2 = pd.DataFrame.from_dict(dict2)


some_df = pd.merge(df1, df2, on = 'Inv', how='outer')

输出看起来像:


    ID_x    Inv    ID_y

X\191       4      X191

X\192       4      X191

733         1       NaN

X215        3      X215

X215        3  BL000002

BL000002    3      X215

BL000002    3  BL000002

我怎样才能合并,以便我让它一对一地加入而不是混合和匹配。


我不能在合并中使用任何其他列,因为它们在实际数据中会有所不同。


编辑和解释 对不起。我说得不够清楚。列 ID 不一致。我也不能保证它是否总是一个子字符串。但发票值必须相同。这是人类一年多来输入的,大约有 15K 行。我需要对它们进行排序,以使具有相同 Invoice 值的那些彼此相邻,因此当其中一个数据帧(最初是 Excel 表)中缺少某些内容时,手动验证会更容易


蛊毒传说
浏览 181回答 3
3回答

翻翻过去那场雪

我认为一个简单的列表查找就可以解决问题:df1['new_id'] = df1.apply(lambda row: row['ID'] if row['ID'] in df2['ID'].tolist() else "", axis=1)     ID  Invoice new_id0  X191        4   X1911  X192        4       2  X212        1       3  X215        3   X2154  X319        3   X319找到要删除的内容后,您可以执行以下操作(我假设 ID 有\, ., '@' ):df['ID'] = df['ID'].str.replace(r'\\|\.|@', '')

紫衣仙女

您需要一个额外的cumcount基于列:u = df1.assign(Cnt=df1.groupby('Inv').cumcount())v = df2.assign(Cnt=df2.groupby('Inv').cumcount())u.merge(v, on=['Inv', 'Cnt'], how='left').drop('Cnt', 1)       ID_x  Inv      ID_y0     X\191    4      X1911     R\192    4       NaN2       733    1       NaN3      X215    3      X2154  BL000002    3  BL000002

Qyouu

试试下面:您正在寻找pandas.merge_asof. 它允许您在一个键上组合 2 个 DataFrame,在这种情况下是 time,而不要求它们完全匹配。您可以选择优先匹配的方向,但在这种情况下,很明显您想要最近的>>> pd.merge_asof(df2.sort_values('Inv'), df1.sort_values('Inv'), on='Inv', direction='nearest')  ID_x  Inv  ID_y 0  215    3  X3191  319    3  X3192  191    4  X192
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python