[英]How to compare non-identical lists and derive values from a dictionary in Python?
[英]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
所以我们只需要通过merge
或reindex
来对齐行/列索引。
merge
对齐外部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
将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
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
子集化的行。
在您的示例中, df1
是df2
的子集,因此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.