4

この質問は関連しています (ただし、同じではありません) 「numpy.unique は、どの点で一意のリストを生成しますか?

セットアップ:

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

4

1 に答える 1

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)
于 2013-05-06T14:58:38.127 に答える