Numpy: python3:对具有不同项目类型的dtype = object数组进行唯一回归(Trac#2188)

创建于 2012-10-19  ·  18评论  ·  资料来源: numpy/numpy

_ @yarikoptic于2012年7月23日发布的原始票证http://projects.scipy.org/numpy/ticket/2188 ,已分配给未知人

针对当前的主设备(也存在于1.6.2中)进行了测试:

如果使用python2.x系列,它可以正常运行,而无需呕吐:

$> python2.7 -c 'import numpy as np; print repr(repr(np.unique(np.array([1,2, None, "str"]))))' 
'array([None, 1, 2, str], dtype=object)'

注意:如果尚未提交,我将在此处分别报告repr的错误

它与python3.x完全失败:

$> python3.2 -c 'import numpy as np; print(repr(repr(np.unique(np.array([1,2,None, "str"])))))'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.2/dist-packages/numpy/lib/arraysetops.py", line 194, in unique
    ar.sort()
TypeError: unorderable types: int() > NoneType()

每当恕我直言,它必须正确运行-unique()动作的语义不应暗示对元素进行排序的能力

00 - Bug numpy.core

最有用的评论

有任何更新吗? 尝试在dtype为“ object”且缺少值的pandas DataFrame列上使用scikit-learn的LabelEncoder时遇到此错误

所有18条评论

关于这个问题有什么新主意吗?

实现unique的唯一选项是:

  • 对数组排序
  • 将所有内容放入哈希表
  • 对所有对象进行蛮力==比较

只有排序和散列策略才具有合理的速度,只有排序和全部反对策略才具有针对大型阵列的合理的内存开销。 因此,我想我们可以将后备选项添加到唯一的地方,如果排序不起作用,那么它将尝试其他策略之一? 但是OTOH的功能有时有时会突然消耗大量CPU或内存,具体取决于您提供的输入,因此不好。

我想我会在补丁上+1,该补丁为np.unique添加了strategy = {“ sort”,“ hash”,“ bruteforce”}选项,因此拥有怪异数据的用户可以决定哪种方式对他们的情况有意义。 如果你想写这样的东西:-)

起初我想知道它是否可以对无法排序的项目进行排序+哈希表(在对dtype对象数组的元素进行排序时不检查是否使用cmp元素),因此排序__cmp__可以将它们放在“先到先得” -“先行”订单?
但是后来意识到,它不能为不可比较的类型提供一般的缓解,例如,当它是int和str的混合...时,我想知道对于dtype = object是否可以推断出第一个参与的dtypes和'unique '(可能通过排序)在每个dtype中是否可能依赖哈希表来查找没有__cmp__ dtype?

仅针对那些可能需要解决方法的人,这是我通过针对我的案例的内置集中的“散列”操作来实现的方法:

$> python3.3 -c 'import numpy as np; print(np.array(list(set([1,2,"str", None])), dtype=object))' 
[None 1 2 'str']

不知道你刚才说了什么:-)

但进一步想想,对于dtype = object,排序确实是不可靠的
无论如何。 我可能已经写了几十个覆盖eq的类,但是
保留默认的lt ,这意味着基于排序的唯一性将
默默地返回错误答案。 我猜这是一个非常讨厌的错误。

如果对象是可哈希的,那么您可以设置(arr)以获得唯一
元素,但不能保证它们通常是可哈希的。 (但至少
每个对可哈希对象都应该_work_,这是不正确的
进行排序。)也许这将是更好的默认实现
np.unique用于对象数组。

2013年9月17日,星期二,下午5:40,Yaroslav Halchenko <
[email protected]>写道:

起初我想知道它是否可以排序+哈希表不可排序
项目(在对以下元素进行排序时,不检查是否使用_cmp_个元素
dtype对象数组),以便对cmp进行排序可以将它们放在
“先到先得”顺序?
但后来意识到,这通常并不能减轻
不可比拟的类型,例如,当它是int和str的组合时...所以我想知道
如果对于dt​​ype = object,则可以推断出首次参与
dtype和每个dtype中的“唯一”(可能通过排序)
在没有cmp的dtypes的哈希表上?

-
直接回复此电子邮件或在Gi tHub上查看它

gy ... ok-Python中的残酷描述:

def bucketed_unique(a):
    buckets = {}
    for x in a:
        t = type(x)
        if not (t in buckets):
            buckets[t] = bucket = []
        else:
            bucket = buckets[t]
        bucket.append(x)
    out = []
    for bucket in buckets.itervalues():
        # here could be actually set of conditions instead of blind try/except
        try:
            out.append(np.unique(bucket))
        except:
            out.append(np.array(list(set(bucket)), dtype=object))
    return np.hstack(out)
print bucketed_unique([1, 2, 'str', None, np.nan, None, np.inf, int])
[1 2 'str' None <type 'int'> nan inf]

肯定的事情-不应对非对象ndarray进行“存储桶”

该算法不使用==作为其唯一性定义。 的对象
不同的类型可以是==。 (简单示例:1、1.0)。 它的定义不
对应于任何标准的python概念。
2013年9月17日18:01,“ Yaroslav Halchenko” [email protected]写道:

肯定的事情-不应对非对象ndarray进行“存储桶”

-
直接回复此电子邮件或在Gi tHub上查看它

确实! 不确定,但可能需要对各个存储区进行事后分析……btw atm问题也显示了其自身,以便与复数进行比较:

$> python3.3 -c 'import numpy as np; print(np.unique(np.array([1, 1.0, 1+0j], dtype=object)))'  
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 194, in unique
    ar.sort()
TypeError: unorderable types: float() > complex()

$> python -c 'import numpy as np; print(np.unique(np.array([1, 1.0, 1+0j], dtype=object)))' 
[1]

尽管有第二种想法-所有唯一选择(int / float / complex)中的“唯一”值dtype应该是什么? 使用非对象数组很明显...不是异构对象数组-可能甚至应该保持不同的dtypes ...

这是我解决py3中混合int / str的argsort方式: https :

在对象dtypes中的字符串之前对int进行排序
使用哈希表映射位置以获取索引器
我认为相当快

使用pandas hashtable实现,但很容易换出/改编成c代码

有人想为此摇摆吗? 不确定如何处理记录dtype。

有任何更新吗? 尝试在dtype为“ object”且缺少值的pandas DataFrame列上使用scikit-learn的LabelEncoder时遇到此错误

这个真的很老。 仍然有意义吗?

至少在debian中使用1.15.4似乎是这样:

$> python3 --version
Python 3.6.5

$> PYTHONPATH=.. python3 -c 'import numpy as np; print(np.__version__); print(repr(repr(np.unique(np.array([1,2,None, "str"])))))'                                                                                   
1.15.4
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 233, in unique
    ret = _unique1d(ar, return_index, return_inverse, return_counts)
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 281, in _unique1d
    ar.sort()
TypeError: '<' not supported between instances of 'NoneType' and 'int'

绝对仍然有意义。 刚遇到这个问题,试图在对象数组上调用np.unique(x, return_inverse=True)

关于_how_的工作原理,当排序未定义时:我更喜欢慢速算法而不是引发错误的现状。 (根据我的经验,通常,如果需要高性能算法,则不应该使用对象数组作为开始。)

我认为这是功能要求,而不是错误。 该文档明确指出:

返回数组的_sorted_个唯一元素。

对于像[1, None]这样的数组,在python 3中不存在这样的排序数组,因为排序不再是定义明确的。

可以选择_not_返回排序后的数组会很不错,这样可以进行一些优化。

此页面是否有帮助?
0 / 5 - 0 等级