2015-10-18 24 views
3

我有一个numpy的阵列,indices得到最小值:的Python如何找到独特的条目,并从匹配阵列

array([[ 0, 0, 0], 
     [ 0, 0, 0], 
     [ 2, 0, 2], 
     [ 0, 0, 0], 
     [ 2, 0, 2], 
     [95, 71, 95]]) 

我有相同长度的另一个数组称为distances

array([ 0.98713981, 1.04705992, 1.42340327, 74.0139111 , 
    74.4285216 , 74.84623217]) 

indices中的所有行都在distances数组中匹配。问题是,indices阵列中存在重复项,并且它们在相应的distances阵列中具有不同的值。我想获得所有三元指数的最小距离,并抛弃其他指数。因此,与上面的投入,我想输出:

indicesOUT = 
array([[ 0, 0, 0], 
     [ 2, 0, 2], 
     [95, 71, 95]]) 

distancesOUT= 
array([ 0.98713981, 1.42340327, 74.84623217]) 

我目前的策略如下:

import numpy as np 

indicesOUT = [] 
distancesOUT = [] 

for i in range(6): 
    for j in range(6): 
     for k in range(6): 
      if len([s for s in indicesOUT if [i,j,k] == s]) == 0: 
       current = np.array([i, j, k]) 
       ind = np.where((indices == current).all(-1) == True)[0] 
       currentDistances = distances[ind] 
       dist = np.amin(distances) 
       indicesOUT.append([i, j, k]) 
       distancesOUT.append(dist) 

的问题是,实际的阵列具有每个约4万台,所以这种方法太慢了。做这件事最有效的方法是什么?

回答

2

这实质上是一个分组操作,NumPy没有很好的优化它。幸运的是,Pandas软件包有一些非常快速的工具,可以适应这个确切的问题。 通过以上数据,我们可以这样做:

import pandas as pd 

def drop_duplicates(indices, distances): 
    data = pd.Series(distances) 
    grouped = data.groupby(list(indices.T)).min().reset_index() 
    return grouped.values[:, :3], grouped.values[:, 3] 

和输出的数据是

array([[ 0., 0., 0.], 
     [ 2., 0., 2.], 
     [ 95., 71., 95.]]), 
array([ 0.98713981, 1.42340327, 74.84623217]) 

我的基准测试表明,对于400万点的元素,这应该大约一秒钟运行:

indices = np.random.randint(0, 100, size=(4000000, 3)) 
distances = np.random.random(4000000) 
%timeit drop_duplicates(indices, distances) 
# 1 loops, best of 3: 1.15 s per loop 

如上所述,索引的输入顺序不一定会保留;保持原来的秩序需要更多的思考。