合并两个数据框而不创建后缀

时间:2019-12-06 17:03:42

标签: python dataframe merge data-cleaning

我想通过合并两个单独的数据帧来创建一个新的数据帧。数据帧共享一个公共密钥和一些公共列。此公共列还包含一些但不是全部相同的值。我想删除重复的值,并使两个值在每个单元格中都不同。我的数据看起来像这样:

左:

key1  valueZ  valueX  valueY
 A    bob     1       4
 B    jes     8       5
 C    joe     3       6

右:

key1  valueZ  valueX  valueY  valueK
 A    sam     7       4       hill town
 B    beth    8       11      market
 C    joe     9       12      mall

预期输出为:

key1    valueZ     valueX     valueY   valueK 
A       bob/sam      1/7       4       hill town  
B       jes/beth     8         5/11    market       
C       joe          3/9       6/12    mall     

1 个答案:

答案 0 :(得分:1)

您需要执行几个步骤。

这是我的设置供参考:

import pandas as pd
# define Data Frames
left = pd.DataFrame({
    'key1': ['A', 'B', 'C'],
    'valueZ': ['bob', 'jes', 'joe'],
    'valueX': [1, 8, 3],
    'valueY': [4, 5, 6]
})
right = pd.DataFrame({
    'key1': ['A', 'B', 'C'],
    'valueZ': ['sam', 'beth', 'joe'],
    'valueX': [7, 8, 9],
    'valueY': [4, 11, 12],
    'valueK': ['hill town', 'market', 'mall']
})

现在我有两个DataFrame对象。它们是leftright,并且与您的示例匹配。

为了结合您想要的方式,我需要知道两个数据框之间共有哪些列,以及列的最终列表。我还在此处定义键列,以简化配置。您可以这样做:

# determine important columns
keyCol = 'key1'
commonCols = list(set(left.columns & right.columns))
finalCols = list(set(left.columns | right.columns))
print('Common = ' + str(commonCols) + ', Final = ' + str(finalCols))

哪个给:

Common = ['valueZ', 'valueX', 'valueY', 'key1'], Final = ['valueZ', 'key1', 'valueK', 'valueX', 'valueY']

接下来,您将像往常一样将两个数据框连接起来,但是给两个数据框中的列添加后缀(此处的文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html

# join dataframes with suffixes
mergeDf = left.merge(right, how='left', on=keyCol, suffixes=('_left', '_right'))

最后,您将使用所需的任何逻辑组合公共列。合并后,您可以从数据框中删除带后缀的列。下面的例子。您可以通过更有效的方式进行此操作,但是为了清晰起见,我想对其进行分解。

# combine the common columns
for col in commonCols:
    if col != keyCol:
        for i, row in mergeDf.iterrows():
            leftVal = str(row[col + '_left'])
            rightVal = str(row[col + '_right'])
            print(leftVal + ',' + rightVal)
            if leftVal == rightVal:
                mergeDf.loc[i, col] = leftVal
            else:
                mergeDf.loc[i, col] = leftVal + '/' + rightVal

# only use the finalCols
mergeDf = mergeDf[finalCols]

这给出了:

     valueZ key1     valueK valueX valueY
0   bob/sam    A  hill town    1/7      4
1  jes/beth    B     market      8   5/11
2       joe    C       mall    3/9   6/12