Pandas"只能比较标记相同的DataFrame对象"错误

use*_*633 47 python pandas

我正在使用Pandas比较加载到两个数据帧(uat,prod)的两个文件的输出:...

uat = uat[['Customer Number','Product']]
prod = prod[['Customer Number','Product']]
print uat['Customer Number'] == prod['Customer Number']
print uat['Product'] == prod['Product']
print uat == prod

The first two match exactly:
74357    True
74356    True
Name: Customer Number, dtype: bool
74357    True
74356    True
Name: Product, dtype: bool
Run Code Online (Sandbox Code Playgroud)

对于第三次打印,我收到一个错误:只能比较标记相同的DataFrame对象.如果前两个比较好,第三个有什么问题?

谢谢

And*_*den 50

这里有一个小例子来演示这个(它只适用于DataFrames,而不是系列,直到它适用于两者的Pandas 0.19):

In [1]: df1 = pd.DataFrame([[1, 2], [3, 4]])

In [2]: df2 = pd.DataFrame([[3, 4], [1, 2]], index=[1, 0])

In [3]: df1 == df2
Exception: Can only compare identically-labeled DataFrame objects
Run Code Online (Sandbox Code Playgroud)

一种解决方案是首先对索引进行排序(注意:某些函数需要排序索引):

In [4]: df2.sort_index(inplace=True)

In [5]: df1 == df2
Out[5]: 
      0     1
0  True  True
1  True  True
Run Code Online (Sandbox Code Playgroud)

注意:对列的顺序==也很敏感,因此您可能必须使用sort_index(axis=1):

In [11]: df1.sort_index().sort_index(axis=1) == df2.sort_index().sort_index(axis=1)
Out[11]: 
      0     1
0  True  True
1  True  True
Run Code Online (Sandbox Code Playgroud)

注意:这仍然可以提升(如果索引/列在排序后没有相同标记).

  • @ R.Cox我猜您正在执行类似df = df.sort_index(inplace = True)的操作,如果您就地使用,则不需要df =,它会修改/更新df DataFrame /变量,表达式返回None。 (2认同)

Cor*_*ump 26

如果不需要比较,您也可以尝试删除索引列:

print(df1.reset_index(drop=True) == df2.reset_index(drop=True))
Run Code Online (Sandbox Code Playgroud)

我在单元测试中使用了相同的技术,如下所示:

from pandas.util.testing import assert_frame_equal

assert_frame_equal(actual.reset_index(drop=True), expected.reset_index(drop=True))
Run Code Online (Sandbox Code Playgroud)

  • 上帝祝福你。我正在努力解决类似行无法在不同 DataFrame 之间进行比较的问题,并且删除索引允许它执行比较。 (3认同)

Sha*_*aza 11

比较两个 DataFrame 时,必须确保第一个 DataFrame 中的记录数与第二个 DataFrame 中的记录数匹配。在我们的示例中,两个 DataFrame 中的每一个都有 4 条记录,其中有 4 个产品和 4 个价格。

例如,如果其中一个 DataFrame 有 5 个产品,而另一个 DataFrame 有 4 个产品,并且您尝试运行比较,则会收到以下错误:

ValueError:只能比较相同标签的系列对象

这应该有效

import pandas as pd
import numpy as np

firstProductSet = {'Product1': ['Computer','Phone','Printer','Desk'],
                   'Price1': [1200,800,200,350]
                   }
df1 = pd.DataFrame(firstProductSet,columns= ['Product1', 'Price1'])


secondProductSet = {'Product2': ['Computer','Phone','Printer','Desk'],
                    'Price2': [900,800,300,350]
                    }
df2 = pd.DataFrame(secondProductSet,columns= ['Product2', 'Price2'])


df1['Price2'] = df2['Price2'] #add the Price2 column from df2 to df1

df1['pricesMatch?'] = np.where(df1['Price1'] == df2['Price2'], 'True', 'False')  #create new column in df1 to check if prices match
df1['priceDiff?'] = np.where(df1['Price1'] == df2['Price2'], 0, df1['Price1'] - df2['Price2']) #create new column in df1 for price diff 
print (df1)
Run Code Online (Sandbox Code Playgroud)

来自https://datatofish.com/compare-values-dataframes/的示例


fly*_*man 8

在问这个问题的时候,Pandas 中没有另一个函数来测试相等性,但它已经被添加了一段时间: pandas.equals

你像这样使用它:

df1.equals(df2)
Run Code Online (Sandbox Code Playgroud)

一些区别==是:

  • 您没有收到问题中描述的错误
  • 它返回一个简单的布尔值。
  • 同一位置的 NaN 值被认为是相等的
  • 2 DataFrames 需要具有相同dtype才能被视为相等,请参阅此 stackoverflow 问题


pap*_*ees 7

Flyingdutchman 的答案很好错误:它使用,这将在您的情况下DataFrame.equals返回。False相反,您想要使用DataFrame.eq,它将返回True

似乎DataFrame.equals忽略了数据帧的索引,而DataFrame.eq使用数据帧的索引进行对齐,然后比较对齐的值。这是一个引用Pandas 核心问题的机会:

这里有一个需要记住的基本原则:数据对齐是内在的。除非您明确这样做,否则标签和数据之间的链接不会被破坏。

正如我们在下面的示例中看到的,除非明确要求,否则数据对齐既不会被破坏,也不会被强制执行。所以我们有三种不同的情况。

  1. 关于对齐方式,没有给出明确的指示:==又名DataFrame.__eq__

   In [1]: import pandas as pd
   In [2]: df1 = pd.DataFrame(index=[0, 1, 2], data={'col1':list('abc')})
   In [3]: df2 = pd.DataFrame(index=[2, 0, 1], data={'col1':list('cab')})
   In [4]: df1 == df2
   ---------------------------------------------------------------------------
   ...
   ValueError: Can only compare identically-labeled DataFrame objects

Run Code Online (Sandbox Code Playgroud)
  1. 对齐方式明显被破坏:DataFrame.equals, DataFrame.values, DataFrame.reset_index(),
    In [5]: df1.equals(df2)
    Out[5]: False

    In [9]: df1.values == df2.values
    Out[9]: 
    array([[False],
           [False],
           [False]])

    In [10]: (df1.values == df2.values).all().all()
    Out[10]: False

Run Code Online (Sandbox Code Playgroud)
  1. 明确强制对齐:DataFrame.eq, DataFrame.sort_index(),

    In [6]: df1.eq(df2)
    Out[6]: 
       col1
    0  True
    1  True
    2  True

    In [8]: df1.eq(df2).all().all()
    Out[8]: True
    
Run Code Online (Sandbox Code Playgroud)

我的答案是从 pandas 版本开始1.0.3

PS当您将数据帧与其自身进行比较时,它会自动对齐,因此我们可能会忘记对齐。这是否意味着以上所有方式都给你了True仅适用于没有缺失值的数据框。但是,如果数据帧包含缺失值,则equals()产生True,并且所有其他方式产生False。这是因为equals()将两个NaNs 视为相等,这是非常不寻常的(按照惯例,np.nan == np.nanFalse)。