Numpy.unique行为(扁平化不一致?)

时间:2014-09-05 17:35:33

标签: python numpy unique

我有两个列表,我需要找到与唯一对相关联的索引(我能找到的所有SO帖子只对这些对本身感兴趣)。我一直试图用numpy.unique来做这件事,但是我很奇怪。我压缩了列表以创建元组列表,然后set()np.unique()成功地仅限于唯一对,但我想要的是原始列表中的索引。 unique的文档表明,如果return_inverse=True,它将返回这些文档。但是,如果设置与否,我会得到不同程度的“扁平化”。

在这个例子中,我使用字符串只是为了避免任何比较问题,实际上它们是浮点数。

import numpy as np

l_1 = ['12.34', '12.34', '12.34', '12.34', '56.78', '56.78', '90.12', '90.12']
l_2 = ['-1.23', '-1.23', '-4.56', '-4.56', '-6.78', '-6.78', '-9.01', '-9.01']
ll = zip(l_1, l_2)

ull1 = np.unique(ll)

ull2, inds = np.unique(ll, return_inverse=True)

在第一种情况下,对被保留为输出中的第二维。在第二种情况下,甚至元组都被压平,从而破坏了对。

In [1]: ull1
Out[1]: 
array([['-9.01', '90.12'],
       ['-1.23', '12.34'],
       ['-6.78', '56.78'],
       ['-4.56', '12.34']], 
      dtype='|S5')

In [2]: ull2
Out[2]:
array(['-1.23', '-4.56', '-6.78', '-9.01', '12.34', '56.78', '90.12'], 
      dtype='|S5')

这是故意的吗?是否有某种方法可以让unique在第一种情况下给出我想要的索引(类似于[[6,7], [0,1], [4,5], [2,3]])?我无法从文档中看出前者或后者的行为是否奇怪。

我需要索引来操作类似列表中的其他值。如果我可以访问大熊猫,我会使用它,但我必须运行的计算机只有一个非常老版本的numpy和没有熊猫。然而,在numpy 1.8.1中仍然会发生同样的事情。我知道我可以做以下事情:

sll = list(set(ll))
for i in range(len(sll)):
    inds = np.where([val == sll[i] for val in ll])
    # I do my operations here using inds

但我希望有更优雅的东西?

1 个答案:

答案 0 :(得分:3)

版本1.8.1中numpy.unique的{​​{3}}从以下内容开始:

try:
    ar = ar.flatten()
except AttributeError:
    if not return_inverse and not return_index:
        return np.sort(list(set(ar)))
    else:
        ar = np.asanyarray(ar).flatten()

如果输入不是数组且return_inversereturn_index不存在,则例程委托Python内置函数来查找唯一元素。它的方式是错误的;它不执行source code保证的扁平化:

  

输入数组。如果它还不是1-D,它将被展平。

正如Jaime在评论中指出的那样,这已在当前的NumPy主分支中得到修复。


我相信您可以通过将两个列表打包到documentation来获得所需的结果。我不知道numpy.unique是否采用结构化数组,但如果没有,则可以使用structured array来复制其行为,该文档记录了如何将其与结构化数组一起使用。