【发布时间】:2015-12-22 14:44:33
【问题描述】:
为清楚起见,我将从我的代码中摘录一段并使用通用名称。我有一个类 Foo() 将 DataFrame 存储到属性中。
import pandas as pd
import pandas.util.testing as pdt
class Foo():
def __init__(self, bar):
self.bar = bar # dict of dicts
self.df = pd.DataFrame(bar) # pandas object
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.__dict__ == other.__dict__
return NotImplemented
def __ne__(self, other):
result = self.__eq__(other)
if result is NotImplemented:
return result
return not result
但是,当我尝试比较 Foo 的两个实例时,我得到一个与比较两个 DataFrame 的歧义相关的异常(如果没有 Foo.__dict__ 中的 'df' 键,比较应该可以正常工作)。
d1 = {'A' : pd.Series([1, 2], index=['a', 'b']),
'B' : pd.Series([1, 2], index=['a', 'b'])}
d2 = d1.copy()
foo1 = Foo(d1)
foo2 = Foo(d2)
foo1.bar # dict
foo1.df # pandas DataFrame
foo1 == foo2 # ValueError
[Out] ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
幸运的是,pandas 具有用于断言两个 DataFrame 或 Series 是否为真的实用函数。如果可能的话,我想使用这个函数的比较操作。
pdt.assert_frame_equal(pd.DataFrame(d1), pd.DataFrame(d2)) # no raises
有几个选项可以解决两个Foo 实例的比较:
- 比较
__dict__的副本,其中new_dict缺少df 键 - 从
__dict__中删除df键(不理想) - 不要比较
__dict__,而只比较它的一部分包含在一个元组中 - 重载
__eq__以方便 pandas DataFrame 比较
从长远来看,最后一个选项似乎最可靠,但我不确定最佳方法。最后,我想重构 __eq__ 以比较来自 Foo.__dict__ 的所有项目,包括 DataFrames(和系列)。关于如何实现这一点的任何想法?
【问题讨论】:
-
为什么不为数据框和系列创建子类,并编写自己的
__eq__函数?您可以在其他情况下超级原件。
标签: python pandas overloading equality