【问题标题】:Python: Compare two Pandas DataFrames and get indices of differencesPython:比较两个 Pandas DataFrame 并获取差异索引
【发布时间】:2019-09-24 18:38:09
【问题描述】:

我想比较两个 Pandas DataFrame 并获取差异的索引。

import numpy as np
import pandas as pd

rng = pd.date_range('2019-03-04', periods=5)
cols = ['A', 'B', 'C', 'D']

df1 = pd.DataFrame(np.arange(20).reshape(5, 4), index=rng, columns=cols)
df2 = pd.DataFrame(np.arange(20).reshape(5, 4), index=rng, columns=cols)

df2.iloc[2, 2] = 100
df2.iloc[3, 1] = 50

df1.equals(df2)  # OK, good to know, but where is the difference?
df1 == df2  # Nice, too. But I'm interested in the indices!

# I need a list containing [(2,2), (3,1)]. Even more intuitive would be something like [('2019-03-06', 'C'), ('2019-03-07', 'B')]

编辑:我不一定需要一个列表,但需要一些东西来识别索引。也就是说,如果有一种简单直观的方法可以在没有列表的情况下解决该问题,那很好。但是,列表也可以。

【问题讨论】:

    标签: python pandas compare


    【解决方案1】:

    我想你可以像下面这样使用np.where

    r, c = np.where(df1 != df2)
    list(zip(r,c))
    

    返回

    [(2, 2), (3, 1)]
    

    编辑

    如果数据帧具有不同类型的索引,上述方法将不起作用,在这种情况下,应该比较 numpy 数组

     r, c = np.where(df1.values != df2.values)
    

    【讨论】:

    • 您假设索引是从 0 到 n ,有时我们有不同类型的索引,例如 ['a','b'.......'x']
    • 这看起来已经是一个合理的解决方案了。我们可以将结果转换为标记索引列表(请参阅我编辑的问题)?基本上从iloc 移动到loc
    • 您可以检索索引和列名list(zip(df1.index[r], df1.columns[c])),它返回[(Timestamp('2019-03-06 00:00:00'), 'C'), (Timestamp('2019-03-07 00:00:00'), 'B')]
    • 您也可以使用r, c = np.nonzero(df1.values != df2.values)。根据文档 (docs.scipy.org/doc/numpy/reference/generated/numpy.where.html),使用 np.nonzero 是首选方式。无论如何,我喜欢那个解决方案,因为从这里我可以轻松地检索到 @stahamtan 正确指出的索引和列名。
    【解决方案2】:

    这行得通吗:

    np.array(np.nonzero(df1.ne(df2).values)).transpose()
    

    输出:

    array([[2, 2],
       [3, 1]], dtype=int64)
    

    另一种方式:

    df1.mask(df1.eq(df2)).stack().index.values
    

    输出:

    array([(2, 2), (3, 1)], dtype=object)
    

    【讨论】:

    • 顺便说一句,你能解释一下为什么不投票吗?这个答案确实解决了问题
    • 您也可以使用np.transpose(np.nonzero(df1.values != df2.values)) 来获得相同的结果。
    • 其实第二种方法更好地回答了你的问题,但速度较慢。
    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    相关资源
    最近更新 更多