Python pandas sort_值抛出ValueError:分类类别必须唯一

Python pandas sort_值抛出ValueError:分类类别必须唯一,python,python-3.x,pandas,dataframe,Python,Python 3.x,Pandas,Dataframe,我有以下DataFrameschema: |str|u A | str|B | co|u A | co|u B |……|一氧化碳| 其中co_A和co_B代表自定义对象 这些对象继承了对象,并定义了丰富的比较方法 FWIW:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 我想做的是按两个自定义列进行排序,这就是混淆的地方 以下代码按预期工作: df.so

我有以下
DataFrame
schema:

|str|u A | str|B | co|u A | co|u B |……|一氧化碳|

其中
co_A
co_B
代表自定义对象


这些对象继承了
对象
,并定义了丰富的比较方法

FWIW:
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


我想做的是按两个自定义列进行排序,这就是混淆的地方

以下代码按预期工作:

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
的某些组合确实有效,而其他组合则无效


我认为这可能是混合类型的原因,所以我删除了字符串值,只留下自定义对象,错误仍然存在。我在这里一无所知,我将感谢任何帮助


编辑:我正在使用熊猫版本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
类是从库中导入的

我所做的是我直接在jupyter中创建了另一个简单的类,使用与原始类类似的方法来检查数据是否有问题成功了。这更令人困惑。CustomObject类肯定有问题(我没有编写该类,但是,我找不到任何可能导致该问题的内容)

该类应该处理版本比较——可以在gist中找到规范

EDIT3:找到了问题的根本原因,但不知道如何解决

已经实现了自定义对象

class 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__()
类自定义对象:
定义初始化(自,流:str):
如果流为“无”:
raise TypeError()
self.stream=流
定义报告(自我):
返回“{cls!s}(stream={stream!r})”(
cls=self.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
stream=self.stream
)
定义(自我):
返回“{stream!s}”。格式(
stream=self.stream
)
定义(自身、其他):
如果“其他”为“无”:
返回错误
返回self.streamother.stream

#这是个老问题,但我遇到了同样的问题

原因 问题在于,当两个对象相等时(由
\uuuuuu eq\uuuu
函数定义),您的
\uuuuuuu散列\uuuu
函数应始终返回
True

现在情况并非如此,因为您的等价性是基于
属性的,并且您的类使用
对象
散列
函数,它(我相信)基于对象在内存中的位置

解决方案 按照下面的方式定义散列函数可能会达到这个目的

def __hash__(self):
    return hash(self.stream)

你在使用熊猫0.23.0吗?你能提供一些数据来说明这个问题吗?在我的问题中添加了这些信息,谢谢你的注释。谢谢你的评论!我以为它已经死了。。是的,我很难找到答案。我假设可以将等价性与哈希函数分开定义。也就是说,哈希值可能不相等,但对象将通过
=
符号比较相等值。这显然是错误的假设。比较相等的可散列对象必须具有相同的散列值。这里的问题是,哈希在对象生存期内不能更改,而
stream
属性也不能更改,所以我无法使用您的解决方案。