def compare(old, new):
new_cols = new.columns.difference(old.columns)
del_cols = old.columns.difference(new.columns)
new_indx = new.index.difference(old.index)
del_indx = old.index.difference(new.index)
# Now that we've checked new and deleted rows and columns
# `align` the dataframes and check the values
old, new = old.align(new, 'inner')
I, J = np.where(old.ne(new))
c = old.columns
r = old.index
changes = pd.DataFrame([
[r[i], c[j], old.iat[i, j], new.iat[i, j]]
for i, j in zip(I, J)
], columns=['Row', 'Column', 'Old', 'New'])
return changes, new_cols, del_cols, new_indx, del_indx
示范
获取更改数据
changes, new_cols, del_cols, new_indx, del_indx = compare(df_original, df_new)
print(f"""\
New Columns:
{' '.join(new_cols.astype(str))}
Deleted Columns:
{' '.join(del_cols.astype(str))}
New Rows:
{' '.join(new_indx.astype(str))}
Deleted Rows:
{' '.join(del_indx.astype(str))}
Changes:
{changes}
""")
New Columns:
Money
Deleted Columns:
New Rows:
3
Deleted Rows:
Changes:
Row Column Old New
0 1 Office Name BOS Boston
_______________________________________________________
更简单的解决方案
我们可以放弃查找添加和删除的列和行的细分,而只解释
changes
def compare(old, new):
old, new = old.align(new) # Notice I don't use `'inner'` as I did before
I, J = np.where(old.ne(new))
c = old.columns
r = old.index
changes = pd.DataFrame([
[r[i], c[j], old.iat[i, j], new.iat[i, j]]
for i, j in zip(I, J)
], columns=['Row', 'Column', 'Old', 'New'])
return changes
compare(df_original, df_new)
Row Column Old New
0 0 Money NaN 50
1 1 Money NaN 100
2 1 Office Name BOS Boston
3 2 Money NaN 20
4 3 Money NaN 30
5 3 Office Location NaN Los Angeles
6 3 Office Name NaN LA
7 3 Office Number NaN 8
在本例中,唯一的更改由
'Old'
_______________________________________________________
如果你有
np.nan
但是,如果一个数据帧
None
另一个有
. 我将把它作为练习留给未来的读者。
def compare(old, new):
old, new = old.align(new)
I, J = np.where(old.ne(new))
c = old.columns
r = old.index
data = []
for i, j in zip(I, J):
n = new.iat[i, j]
o = old.iat[i, j]
if pd.notna(n) or pd.notna(o):
data.append([r[i], c[j], o, n])
return pd.DataFrame(data, columns=['Row', 'Column', 'Old', 'New'])