【问题标题】:Combine 2 Dataframes when rows are not matching and put columns side by side for comparison当行不匹配时合并 2 个数据框并将列并排放置以进行比较
【发布时间】:2020-12-23 14:13:38
【问题描述】:

我手头有这些数据框,我想将它们组合成一个数据框,但前提是它们有任何不匹配的行,为了比较起见,我想将数据框的列放在一起。

initial = pd.DataFrame({'ID': ['123', '456', '789', '000'],
                     'Day': ['Mon','Tues','Wed','Thurs'],
                     'Value': ['5', '10', '11', '12'],
                      'Letter': ['Z', 'X', 'C', 'V']}) 

updated = pd.DataFrame({'ID': ['456', '123', '000', '789'],
                      'Day': ['Tues','Mon','Thurs','Wed'],
                       'Value': ['10', '8', '12', '13'],
                      'Letter': ['X', 'Z', 'C', 'V']}) 

合并它们后,我希望它们看起来像这样。 (注意:initial 和 updated 中的 'Value' 列是并排的,'Letter' 列也是如此。

ID Day Value_initial Value_updated Letter_initial Letter_updated
123 Mon 5 8 Z Z
789 Wed 11 13 C C
000 Thurs 12 12 V C

有人知道我该怎么做吗?

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    在您提供的示例数据中,即使ID:000 在Letter 列中也有不匹配的数据。

    试用代码:

    df = pd.merge(initial,updated,on='ID', how='inner',suffixes=('_initial', '_updated'))
    df = df[(df['Day_initial'] != df['Day_updated']) | (df['Value_initial'] != df['Value_updated']) | (df['Letter_initial'] != df['Letter_updated'])]
    df = df.rename(columns={'Day_initial': 'Day'}).drop('Day_updated',axis=1)
    df
    

    打印:

        ID    Day Value_initial Letter_initial Value_updated Letter_updated
    0  123    Mon             5              Z             8              Z
    2  789    Wed            11              C            13              V
    3  000  Thurs            12              V            12              C
    

    替代(根据 cmets):如果要比较的列太多,则以下方法是先从两个 dfs 中删除公共行,然后再进行合并。代码假定initial 中存在的所有ID 也存在于updated 中。

    df1 = initial.sort_values('ID').reset_index(drop=True)
    df2 = updated.sort_values('ID').reset_index(drop=True)
    df3_common = df1[df1.isin(df2)].dropna()
    df1 = df1[~df1.isin(df3_common)].dropna()
    df2 = df2[~df2.isin(df3_common)].dropna()
    df = pd.merge(df1,updated,on='ID', how='inner',suffixes=('_initial', '_updated'))
    df = df.rename(columns={'Day_initial': 'Day'}).drop('Day_updated',axis=1)
    df = df[['ID','Day','Value_initial','Value_updated','Letter_initial','Letter_updated']]
    df
    

    打印:

        ID    Day Value_initial Value_updated Letter_initial Letter_updated
    0  000  Thurs            12            12              V              C
    1  123    Mon             5             8              Z              Z
    2  789    Wed            11            13              C              V
    

    【讨论】:

    • 哦,对了。我意识到了这一点。我已经编辑过了。有没有办法重新排列列?
    • 此外,我想添加这对于几列来说会很好,但假设我们有 100 列,检查每一列是否不等于另一列似乎很粗糙。
    • 只是df = df[['ID','Day','Value_initial','Value_updated','Letter_initial','Letter_updated']]
    • 我添加了一个代码,它可以消除检查是否有很多列的需要。
    【解决方案2】:

    您可以append 而不是合并和drop_duplicates()。然后,pivot 数据框。这也将根据需要排序:

    df = (initial.assign(col='initial')                            # create new col for each dataframe as we merge, so we can use as the column for the pivot later 
          .append(updated.assign(col='updated'))                   # append row-wise so we can use drop_duplicates
          .drop_duplicates(initial.columns, keep=False))           # keep=False drops both rows that are duplicated
          .pivot(index=['ID', 'Day'], columns='col').reset_index() # we transform dataframe from long-to-wide with pivot
    df.columns = [f'{col[0]}_{col[1]}' for col in df.columns]      # fix the names of the columns so they are as desired and not multi-level
    df
    Out[1]: 
       ID_   Day_ Value_initial Value_updated Letter_initial Letter_updated
    0  000  Thurs            12            12              V              C
    1  123    Mon             5             8              Z              Z
    2  789    Wed            11            13              C              V
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多