Pandas Dataframe Merge Where 1 Column Matches,但另一列的值不存在

Pandas Dataframe Merge Where 1 Column Matches, but Another Column's Values are not Present

这几天我一直在尝试使用 Pandas 来解决问题,但我觉得我遗漏了什么。我有 2 个数据框:

data = {'GMC1':[1, 1, 1, 2, 3, 3, 3],
        'Provider1':[100, 101, 102, np.NaN, 104, 105, 106]}

dataframe1 = pd.DataFrame(data)

dataframe1

输出:

GMC1    Provider 1
1       100
1       101
1       102
2       NaN
3       104
3       105
3       106

data2 = {'GMC2':[1, 2, 3, 3, 3],
         'Provider2':[101, 100, 104, 105, 107]}

dataframe2 = pd.DataFrame(data2)

dataframe2

输出:

GMC2    Provider2
1       101
2       100
3       105
3       104
3       107

我想要返回一个数据帧,它加入 GMC1 = GMC2,并返回 Provider1 中不存在的 Provider2 行,GMC1 和 GMC2 的值相同。

预期输出:

GMC1    GMC2    Provider 2
2       2       100
3       3       107

我尝试过各种使用连接的方法,例如:

(dataframe1.merge(dataframe2, left_on='GMC1', right_on='GMC2',
                  how='right')
           .query('Provider1 != Provider2')
)

但他们并没有完全带回我想要的东西。我知道这有点罗嗦,所以我很乐意详细说明。

非常感谢您的帮助!

一种方法是在两个数据帧上创建一个辅助列,我们称之为 ['GP']:

dataframe2['Provider2'] = dataframe2['Provider2'].astype(float)  # setting this to float so the merge will work
dataframe1['GP'] = dataframe1[['GMC1', 'Provider1']].astype(str).agg(' '.join, axis=1)
dataframe2['GP'] = dataframe2[['GMC2', 'Provider2']].astype(str).agg(' '.join, axis=1)

然后,如果我们在此列上合并并排除 NA:

dataframe1.merge(dataframe2, on='GP', how='outer').query('GMC1.isna()')

会 return:

    GMC1    Provider1   GP     GMC2 Provider2
7   NaN     NaN      2 100.0    2.0     100.0
8   NaN     NaN      3 107.0    3.0     107.0

从这里开始,您可以通过一些争论轻松获得所需的解决方案,运行 例如:

result = dataframe1.merge(dataframe2, on='GP', how='outer').query('GMC1.isna()')

result['GMC1'] = result['GP'].apply(lambda x: x.split(' ')[0])

result = result.drop(columns=['GP', 'Provider1'])

将生成您想要的数据框:

    GMC1    GMC2    Provider2
7   2       2.0         100.0
8   3       3.0         107.0

抱歉,回答有点罗嗦,但希望对您有所帮助!

合并确实是可行的方法。但是您必须在 groupby 中进行查询,以仅比较具有相同 GMC 值的提供商:

dataframe1.merge(dataframe2, left_on='GMC1', right_on='GMC2').groupby('GMC1').apply(
    lambda df: df[~df['Provider2'].isin(df['Provider1'].values)]
    )[['GMC1', 'GMC2', 'Provider2']].drop_duplicates().reset_index(drop=True)

符合预期

   GMC1  GMC2  Provider2
0     2     2        100
1     3     3        107

按列和指标参数使用外部联接并按此新列过滤 _merge:

df = dataframe1.merge(dataframe2, 
                      left_on=['GMC1', 'Provider1'],
                      right_on=['GMC2', 'Provider2'], 
                      how='right', 
                      indicator=True)

df = (df.loc[df['_merge'].eq('right_only'), ['GMC1','GMC2','Provider2']]
        .assign(GMC1 = lambda x: x['GMC2']))

print (df)
   GMC1  GMC2  Provider2
1     2     2        100
4     3     3        107