2014-09-05 75 views
2

我有两个列表,我需要找到与唯一对关联的索引(我可以找到的所有SO帖子只对对自己感兴趣)。我一直在尝试使用numpy.unique这样做,但我很奇怪。我压缩列表创建一个元组列表,然后set()np.unique()成功削减到唯一的对,但我想要的是指数到原始列表。 unique的文档表明它将返回那些如果return_inverse=True。但是,如果设定了,我会得到不同程度的“扁平化”。Numpy.unique行为(展平不一致?)

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

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 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 

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

+0

@moarningsun Ahah,我发现了这个问题,但是我没有在那个答案中看到'idx',直到你专门调用它。我觉得我被这个答案的长度和数量弄糊涂了...... – Ajean 2014-09-05 19:46:11

+1

对,如果我链接到特定的答案,它会更好:http://stackoverflow.com/a/16973510/2379410 – 2014-09-05 19:51:32

回答

3

版本的source codenumpy.unique具有以下1.8.1开始:

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的内置插件来找到独特的元素。它这样做的方式是窃听;它不执行扁平化,即documentation保证:

输入数组。如果它不是一维的话,这将会变平。

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


我相信你可以通过打包的两个列表成为一个structured array得到你想要的结果。我不知道numpy.unique是否需要结构化数组,但如果不是,可以使用numpy.sort来复制其行为,该文档记录了如何将它用于结构化数组。

+0

非常好!我甚至没有想到结构化数组,但我只是试了一下,它完全符合我的要求。感谢您对numpy文档的澄清,我还被“这将在扁平化如果它不是已经是1-D”的矛盾混淆。 – Ajean 2014-09-05 19:44:13

+2

那个bug的行为在前一段时间被修复了,请参阅主源代码[here ](https://github.com/numpy/numpy/blob/master/numpy/lib/arraysetops.py#L96),这也是进入1.9测试版。 – Jaime 2014-09-05 20:22:15

+0

@Jaime:啊,很高兴知道。我没想过要检查代码的开发版本。 – user2357112 2014-09-05 23:22:10