【问题标题】:Python, Pandas: Compare two dataframes and return combinedPython,Pandas:比较两个数据框并返回组合
【发布时间】:2021-01-10 15:56:44
【问题描述】:

晚上好,

我想知道,比较两个数据帧并返回它们的组合的最佳方法是什么?或者如果 pandas 内部甚至有一个内置函数?

例如,这是我的两个数据框:

数据框 01:

first_name | age | id | value_a | value_b | value_c
peter      | 37  | 19 | 4562    | 78      | 21.5
jane       | 32  | 5  | 3832    | 85      | 17.0
michael    | 43  | 41 | 2195    | 63      | 44.4

数据框 02:

first_name | age | id | value_a | value_b | value_c
sarah      | 51  | 2  | 63      | 81      | 4.1
peter      | 37  | 19 | 4562    | 81      | 21.5
tom        | 22  | 89 | 107     | 14      | 0.0
michael    | 43  | 41 | 1838    | 63      | 44.4

如您所见,整个数据框(Dataframe 02)中有一些新条目,并且还列出了一些已经存在的条目 --> 在这些行中进行了一些更改! 我想要实现的是一个新的(?)数据框,其中包含所有新行、已经存在的行和更新的行!在这种情况下:

新数据框

first_name | age | id | value_a | value_b | value_c
peter      | 37  | 19 | 4562    | 81      | 21.5
jane       | 32  | 5  | 3832    | 85      | 17.0
michael    | 43  | 41 | 1838    | 63      | 44.4
sarah      | 51  | 2  | 63      | 81      | 4.1
tom        | 22  | 89 | 107     | 14      | 0.0

注意事项:

  • 总有一个列(这里:'id')可以被视为不变的键
  • 行数可能不同
  • 列的数量和名称始终保持不变
  • 行的顺序并不重要

感谢您的帮助,祝您有个愉快的夜晚!

【问题讨论】:

  • 你可以使用pd.concatpd.merge

标签: python pandas dataframe compare


【解决方案1】:

既然你问pandas 中是否有内置函数?。答案是肯定的,pandas 中有一个内置函数,可以让您比较标记相同(具有相同索引和列)的数据帧。

有一个 DataFrame.compare 函数在 pandas 版本中可用 >= 1.1.0 并允许您将第一个数据帧与第二个数据帧进行比较并显示差异:

那么,现在让我们看看你所说的例子

  • 总有一个列(这里:'id')可以被视为不变的键
  • 列的数量和名称始终保持不变

因此,为了比较两个数据框,您首先需要 align 两个数据框,这可以在将列 id 设置为常用 index 后使用 DataFrame.align 函数完成两个数据框:

d1, d2 = df1.set_index('id').align(df2.set_index('id'))

现在您可以在对齐的数据帧上使用 DataFrame.compare

d1.compare(d2, keep_equal=True)

结果:

         first_name     age           value_a         value_b       value_c      
         self    other  self other    self   other    self other    self other
id                                                                            
2         NaN    sarah   NaN  51.0     NaN    63.0     NaN  81.0     NaN   4.1
5        jane      NaN  32.0   NaN  3832.0     NaN    85.0   NaN    17.0   NaN
19      peter    peter  37.0  37.0  4562.0  4562.0    78.0  81.0    21.5  21.5
41    michael  michael  43.0  43.0  2195.0  1838.0    63.0  63.0    44.4  44.4
89        NaN      tom   NaN  22.0     NaN   107.0     NaN  14.0     NaN   0.0

现在来回答你的第二个问题:

如何实现一个包含所有新行的新(?)数据框, 已经存在的和更新的!

您可以在对齐的数据帧d1d2 上使用DataFrame.comine_first

d2.combine_first(d1)

或者,在未对齐的情况下如下:

df2.set_index('id').combine_first(df1.set_index('id'))

结果:

   first_name   age  value_a  value_b  value_c
id                                            
2       sarah  51.0     63.0     81.0      4.1
5        jane  32.0   3832.0     85.0     17.0
19      peter  37.0   4562.0     81.0     21.5
41    michael  43.0   1838.0     63.0     44.4
89        tom  22.0    107.0     14.0      0.0

【讨论】:

  • 写得好答案.. +1 :)
【解决方案2】:

这是一种方法

>>> (pd.concat([df1, df2])
       .drop_duplicates(subset=['id','first_name'], keep='last')
       .reset_index(drop=True)
       .set_index('first_name')
     )

first_name  |  age   |  id   |   value_a  |  value_b   |   value_c
jane        |   32   |   5   |     3832   |       85   |     17.0
sarah       |   51   |   2   |       63   |       81   |      4.1
peter       |   37   |  19   |     4562   |       81   |     21.5
tom         |   22   |  89   |      107   |       14   |      0.0
michael     |   43   |  41   |     1838   |       63   |     44.4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    相关资源
    最近更新 更多