我有两个数据帧df1和df2。 相同的索引和相同的列名称。 如何构建一个显示差异的数据帧,但只包含至少有一个不同单元格的行? 如果行具有不同的单元格,但有些单元格相同,则保持相同的单元格完好无损。
示例:
df1=pd.DataFrame({1:['a','a'],2:['c','c']})
df2=pd.DataFrame({1:['a','a'],2:['d','c']})
需要输出:
pd.DataFrame({1:['a'],2:['c->d']},index=[0])
此示例中的输出应该是一行数据帧,而不是包含相同行的数据帧
注意:输出应仅包含完整行,这些行在单元格中至少有一个区别
我想要一个有效的解决方案而不按行迭代,而不在DataFrame中创建特殊字符串
答案 0 :(得分:1)
您可以使用this brilliant solution:
def report_diff(x):
return x[0] if x[0] == x[1] else '{}->{}'.format(*x)
In [70]: pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0)
Out[70]:
1 2
0 a c->d
1 a c
对于更复杂的DataFrames:
In [73]: df1
Out[73]:
A B C
0 a c 1
1 a c 2
2 1 2 3
In [74]: df2
Out[74]:
A B C
0 a d 1
1 a c 2
2 1 2 4
In [75]: pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0)
Out[75]:
A B C
0 a c->d 1
1 a c 2
2 1 2 3->4
更新:仅显示已更改/不同的行:
In [54]: mask = df1.ne(df2).any(1)
In [55]: mask
Out[55]:
0 True
1 False
2 True
dtype: bool
In [56]: pd.Panel(dict(df1=df1[mask],df2=df2[mask])).apply(report_diff, axis=0)
Out[56]:
A B C
0 a c->d 1
2 1 2 3->4
答案 1 :(得分:1)
对于扁平内容的良好列表理解如何......
import pandas as pd
import numpy as np
df1=pd.DataFrame({1:['a','a'],2:['c','c']})
df2=pd.DataFrame({1:['a','a'],2:['d','c']})
rows_different_mask = (df1 != df2).any(axis=1)
pairs = zip(df1.values.reshape(1, -1)[0], df2.values.reshape(1, -1)[0])
new_elems = ["%s->%s" %(old, new) if (old != new) else new for old, new in pairs]
df3 = pd.DataFrame(np.reshape(new_elems, df1.values.shape))
print df3
0 1
0 a c->d
1 a c