首页 > 解决方案 > 返回熊猫数据框中的单元格差异

问题描述

这是按预期工作的代码。

来自: 并排输出两个 Pandas 数据帧中的差异 - 突出差异

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

DF1 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.11                     False                "Graduated"
113  Zoe    NaN                     True                  " "
""")
DF2 = StringIO("""id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 "He was late to class"
112  Nick   1.21                     False                "Graduated"
113  Zoe    NaN                     False                "On vacation" """)


df1 = pd.read_table(DF1, sep='\s+', index_col='id')
df2 = pd.read_table(DF2, sep='\s+', index_col='id')


df_all = pd.concat([df1, df2], 
                   axis='columns', keys=['First', 'Second'])

df_final = df_all.swaplevel(axis='columns')[df1.columns[1:]]

def highlight_diff(data, color='yellow'):
    attr = 'background-color: {}'.format(color)
    other = data.xs('First', axis='columns', level=-1)
    return pd.DataFrame(np.where(data.ne(other, level=0), attr, ''),
                        index=data.index, columns=data.columns)

df_final.style.apply(highlight_diff, axis=None)

唯一的问题是我不想要第一行(111),因为没有区别。

如何在不使用 highlight_diff 函数的情况下仅选择更改的行?我想并排返回第 112 行和第 113 行而不突出显示,如 Ted 的回答所示。

标签: pythonpandas

解决方案


df_select = df_final.copy()
df_select.columns = df_final.columns.swaplevel()
duplicate = (df_select['First'] == df_select['Second']).all(axis=1)
df_final = df_final[~duplicate]

说明:我们创建第二个数据框df_select来选择相关行(并复制df_final以便您的原始数据不会被更改)。它的列被交换,因此FirstSecond位于第 0 级。那么您要丢弃的行是 First 和 Second 相同的行。我们更改df_final为仅包含非重复行。

编辑:如果您根本不想使用df_finaldf_all而是:

duplicate = (df_all['First'] == df_all['Second']).drop('Comment', axis=1).all(axis=1)
result = df_all[~duplicate]

(我假设您不想检查评论,类似于之前的过程。如果您确实想要,请删除drop。)


推荐阅读