繁体   English   中英

如何比较 python 中的 2 个不相同的数据帧

[英]How to compare 2 non-identical dataframes in python

我有两个具有相同列顺序但列名和行不同的数据框。 df2行与df1行不同。

df1=     col_id  num  name
      0   1     3     linda
      1   2     4     James

df2=     id     no   name
      0   1     2    granpa
      1   2     6    linda
      2   3     7    sam

这是我需要的 output。 输出具有相同 OLD 和 NEW 值的行,以便用户可以清楚地看到两个数据帧之间的变化:

 result   col_id        num              name   
      0   1             was 3| now 2    was linda| now granpa  
      1   2             was 4| now 6    was James| now linda
      2   was  | now 3  was  | now 7    was      | now sam

如果我理解正确,你想要这样的东西:

new_df = df1.drop(['name', 'num'], axis=1).merge(df2.rename({'id': 'col_id'}, axis=1), how='outer')

Output:

>>> new_df
   col_id  no    name
0       1   2  granpa
1       2   6   linda
2       3   7     sam

由于您的目标只是比较差异,因此请使用DataFrame.compare而不是聚合成字符串。

但是,请注意DataFrame.compare

只能比较具有相同标签(即相同形状、相同行和列标签)的 DataFrame

所以我们只需要通过mergereindex来对齐行/列索引。


通过merge对齐

  1. 外部merge两个 dfs:

     merged = df1.merge(df2, how='outer', left_on='col_id', right_on='id') # col_id num name_x id no name_y # 0 1 3 linda 1 2 granpa # 1 2 4 james 2 6 linda # 2 <NA> <NA> NaN 3 7 sam
  2. merged的帧划分为left / right帧,并将它们的列与set_axis对齐:

     cols = df1.columns left = merged.iloc[:, :len(cols)].set_axis(cols, axis=1) # col_id num name # 0 1 3 linda # 1 2 4 james # 2 <NA> <NA> NaN right = merged.iloc[:, len(cols):].set_axis(cols, axis=1) # col_id num name # 0 1 2 granpa # 1 2 6 linda # 2 3 7 sam
  3. compare对齐的left / right帧(使用keep_equal=True显示相等的单元格):

     left.compare(right, keep_shape=True, keep_equal=True) # col_id num name # self other self other self other # 0 1 1 3 2 linda granpa # 1 2 2 4 6 james linda # 2 <NA> 3 <NA> 7 NaN sam left.compare(right, keep_shape=True) # col_id num name # self other self other self other # 0 <NA> <NA> 3 2 linda granpa # 1 <NA> <NA> 4 6 james linda # 2 <NA> <NA> <NA> <NA> NaN sam

通过reindex对齐

如果您 100% 确定一个 df 是另一个 df 的子集,则reindex子集化的行。

在您的示例中, df1df2的子集,因此reindex df1

df1.assign(id=df1.col_id)          # copy col_id (we need original col_id after reindexing)
   .set_index('id')                # set index to copied id
   .reindex(df2.id)                # reindex on df2's id
   .reset_index(drop=True)         # remove copied id
   .set_axis(df2.columns, axis=1)  # align column names
   .compare(df2, keep_equal=True, keep_shape=True)

#        col_id         num          name
#    self other  self other   self  other
# 0     1     1     3     2  linda granpa
# 1     2     2     4     6  james  linda
# 2  <NA>     3  <NA>     7    NaN    sam

可空整数

通常int不能与nan混合,因此 pandas 转换为float 如果您希望int值保持int (如上面的示例):

  • 使用astype('Int64') (大写I )将int列转换为可为空的整数
  • 或将它们转换为astype(object) (不推荐)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM