如何在Pandas Python中合并时避免笛卡尔

问题描述 投票:2回答:2

我正在尝试合并2个数据集X和Y.数据集X具有连接键列,该列具有重复值。数据集Y具有“连接”键列和一个附加列。数据集图像已在下面上传。问题是由于数据集X中存在重复项,我想避免使用笛卡尔积。我在下面附加了结果数据集图像。这可以通过使用for循环手动合并来手动完成,但这很耗时。任何人都可以提供更好的方法

python pandas merge duplicates cartesian
2个回答
1
投票

使用@Alollz设置:

df_x = pd.DataFrame({'EMM_ID': [610462, 610462, 610462, 610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18]})

你可以用cumcount创建一个新的'key'来加入。

colkey = 'EMM_ID'
df_x = df_x.assign(colkey=df_x.groupby(colkey).cumcount())
df_y = df_y.assign(colkey=df_y.groupby(colkey).cumcount())

df_x[['EMM_ID','colkey']].merge(df_y, on=['EMM_ID','colkey'], how='left')

输出:

   EMM_ID  colkey  ID_home
0  610462       0  81000.0
1  610462       1      NaN
2  610462       2      NaN
3  610462       3      NaN
4   61000       0     18.0
5   61000       1      NaN

1
投票

在这种情况下,由于您只需要带一列,.map可能更合适。我们获取每个EMM_ID组中的第一个值,并仅映射该值。对齐指数确保其余成为NaN

Sample Data

import pandas as pd
import numpy as np
df_x = pd.DataFrame({'EMM_ID': [610462, 610462, 610462, 610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18]})

Code

df_x['ID_home'] = df_x.groupby('EMM_ID').head(1).EMM_ID.map(df_y.set_index('EMM_ID').ID_home)

Output: df_x

   EMM_ID  ID_home
0  610462  81000.0
1  610462      NaN
2  610462      NaN
3  610462      NaN
4   61000     18.0
5   61000      NaN

如果你需要带多个列,那么你可以拆分你的DataFrame,与子集合并,然后连接回一个DataFrame。

df_x = pd.DataFrame({'EMM_ID': [610462,610462,610462,610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18], 'Val_2': ['A', 'F']})

to_merge = df_x.groupby('EMM_ID').head(1)
keep = df_x[~df_x.index.isin(to_merge.index)]

pd.concat([keep, to_merge[['EMM_ID']].merge(df_y)], sort=False).sort_index() 

输出:

   EMM_ID  ID_home Val_2
0  610462  81000.0     A
1  610462      NaN   NaN
1   61000     18.0     F
2  610462      NaN   NaN
3  610462      NaN   NaN
5   61000      NaN   NaN
© www.soinside.com 2019 - 2024. All rights reserved.