我正在使用以下DataFrame
架构:
| str_A | str_B | co_A | co_B | ...... | co_X |
其中co_A
和co_B
代表自定义对象
这些对象继承object
并定义了丰富的比较方法
FWIW:__hash__
方法也被覆盖并调用super().__hash__()
我想要做的是按两个自定义列排序,这就是混乱的地方。
以下代码按预期工作:
df.sort_values(by=['str_A', 'str_B'])
以下代码也适用:
df.sort_values(by=['co_A'])
但不起作用的是:
df.sort_values(by=['co_A', 'co_B'])
抛出
ValueError:分类类别必须是唯一的
事实证明,co_x
和str_x
的某些组合可以正常运作,而其他组合则无效。
我认为这可能是混合类型的原因,所以我删除了字符串值并只留下自定义对象,错误仍然存在。我在这里一无所知,我将不胜感激。
编辑:我使用的是pandas版本0.23.0
要生成我可以重现问题的简单数据,可以使用以下示例代码
def feed():
return type('Feed', (), {
attr: names.get_first_name() if attr.startswith('substr') else names.get_last_name()
for attr in CPE_VERSION_ATTRIBUTE_LIST
})
feed = [feed() for i in range(100)]
EDIT2 :
我使用的是jupyter笔记本,CustomObject
类是从lib导入的。
我所做的是我在jupyter中直接创建另一个简单类,使用与原始方法类似的方法来检查数据是否有问题... 并且它有效。哪个更令人困惑。 CustomObject类一定有问题(我没有编写类,但是,我找不到任何可能导致问题的东西)。
该类应该处理版本比较 - 可以在要点中找到规范 https://gist.github.com/CermakM/011f17e91ffe9efbe35f29738fb23ec2
EDIT3 :找到问题的根本原因,不知道如何解决,但
实现了像
这样的CustomObjectclass CustomObject:
def __init__(self, stream: str):
if stream is None:
raise TypeError()
self.stream = stream
def __repr__(self):
return "{cls!s}(stream={stream!r})".format(
cls=self.__class__.__name__,
stream=self.stream
)
def __str__(self):
return "{stream!s}".format(
stream=self.stream
)
def __lt__(self, other):
if other is None:
return False
return self.stream < other.stream
def __gt__(self, other):
if other is None:
return True
return self.stream > other.stream
# <<<<<<< This causes the issue
# def __eq__(self, other):
# if other is None:
# return False
# return self.stream == other.stream
# =======
def __hash__(self):
return super().__hash__()
如果没有上面注释的代码,它可以正常工作。
答案 0 :(得分:0)
这是一个古老的问题,但我遇到了同样的问题。
问题在于,当两个对象相等时(由__hash__
函数定义),您的True
函数应始终返回__eq__
。
现在不是这种情况,因为您的等效项基于stream
属性,并且您的类使用__hash__
的{{1}}函数,(我相信)该函数基于对象在内存中的位置。
按如下所示定义哈希函数可以解决问题。
object