numpy.unique与numpy.array对象的行为很奇怪

时间:2013-05-06 14:32:34

标签: python numpy

此问题与“numpy.unique generates a list unique in what regard?

有关(但不相同)

设置:

import numpy as np
from functools import total_ordering

@total_ordering
class UniqueObject(object):
    def __init__(self, a):
        self.a = a
    def __eq__(self, other):
        return self.a == other.a
    def __lt__(self, other):
        return self.a < other.a
    def __hash__(self):
        return hash(self.a)
    def __str__(self):
        return "UniqueObject({})".format(self.a)
    def __repr__(self):
        return self.__str__()

np.unique的预期行为:

>>> np.unique([1, 1, 2, 2])
array([1, 2])
>>> np.unique(np.array([1, 1, 2, 2]))
array([1, 2])
>>> np.unique(map(UniqueObject, [1, 1, 2, 2]))
array([UniqueObject(1), UniqueObject(2)], dtype=object)

哪个没问题,有效。但这并不像预期的那样有效:

>>> np.unique(np.array(map(UniqueObject, [1, 1, 2, 2])))
array([UniqueObject(1), UniqueObject(1), UniqueObject(2), UniqueObject(2)], dtype=object)

为什么带有dtype = object的np.array与带有对象的python列表的处理方式不同?

那是:

objs = map(UniqueObject, [1, 1, 2, 2])
np.unique(objs) != np.unique(np.array(objs)) #?

我正在运行numpy 1.8.0.dev-74b08b3Python 2.7.3

1 个答案:

答案 0 :(得分:3)

通过np.unique的来源,似乎实际采取的分支是

else:
    ar.sort()
    flag = np.concatenate(([True], ar[1:] != ar[:-1]))
    return ar[flag]

简单地对术语进行排序,然后取出与前一个不相等的术语。但是不应该这样做吗?哎呀。这是在我身上。您的原始代码定义为__ne__,我在删除比较total_ordering时意外删除了它。

>>> UniqueObject(1) == UniqueObject(1)
True
>>> UniqueObject(1) != UniqueObject(1)
True

重新放入__ne__

>>> UniqueObject(1) != UniqueObject(1)
False
>>> np.array(map(UniqueObject, [1,1,2,2]))
array([UniqueObject(1), UniqueObject(1), UniqueObject(2), UniqueObject(2)], dtype=object)
>>> np.unique(np.array(map(UniqueObject, [1,1,2,2])))
array([UniqueObject(1), UniqueObject(2)], dtype=object)