将索引获取到numpy数组的重复列

时间:2014-02-19 17:51:07

标签: python arrays numpy

我有一个带有重复列的numpy数组:

import numpy as np

A = np.array([[1, 1, 1, 0, 1, 1],
              [1, 2, 2, 0, 1, 2],
              [1, 3, 3, 0, 1, 3]])

我需要找到那些重复的索引或类似的东西:

[0,4]

[1,2,5]

我很难处理Python中的索引。我真的不知道接近它。

由于

我尝试使用此功能首先识别唯一列:

 def unique_columns(data):
     ind = np.lexsort(data)
     return data.T[ind[np.concatenate(([True], any(data.T[ind[1:]]!=data.T[ind[:-1]], axis=1)))]].T

但是我无法从中找出索引。

2 个答案:

答案 0 :(得分:2)

遗憾的是,没有一种简单的方法可以做到这一点。使用np.unique答案。此方法要求您想要唯一的轴在内存中是连续的,并且numpy的典型内存布局在行中是C连续或连续的。幸运的是,numpy使这种转换变得简单:

A = np.array([[1, 1, 1, 0, 1, 1],
              [1, 2, 2, 0, 1, 2],
              [1, 3, 3, 0, 1, 3]])

def unique_columns2(data):
    dt = np.dtype((np.void, data.dtype.itemsize * data.shape[0]))
    dataf = np.asfortranarray(data).view(dt)
    u,uind = np.unique(dataf, return_inverse=True)
    u = u.view(data.dtype).reshape(-1,data.shape[0]).T
    return (u,uind)

我们的结果:

u,uind = unique_columns2(A)

u
array([[0, 1, 1],
       [0, 1, 2],
       [0, 1, 3]]) 
uind
array([1, 2, 2, 0, 1, 2])

我不确定你想从这里做什么,例如你可以这样做:

>>> [np.where(uind==x)[0] for x in range(u.shape[0])]
[array([3]), array([0, 4]), array([1, 2, 5])]

一些时间:

tmp = np.random.randint(0,4,(30000,500))

#BiRico and OP's answer
%timeit unique_columns(tmp)
1 loops, best of 3: 2.91 s per loop

%timeit unique_columns2(tmp)
1 loops, best of 3: 208 ms per loop

答案 1 :(得分:0)

以下是如何处理它的概述。使用numpy.lexsort对列进行排序,这样就可以将所有重复项组合在一起。一旦重复项全部合并在一起,您就可以轻松判断哪些列是重复的,以及与这些列对应的索引。

这是上述方法的实现。

import numpy as np

def duplicate_columns(data, minoccur=2):
    ind = np.lexsort(data)
    diff = np.any(data.T[ind[1:]] != data.T[ind[:-1]], axis=1)
    edges = np.where(diff)[0] + 1
    result = np.split(ind, edges)
    result = [group for group in result if len(group) >= minoccur]
    return result

A = np.array([[1, 1, 1, 0, 1, 1],
              [1, 2, 2, 0, 1, 2],
              [1, 3, 3, 0, 1, 3]])
print(duplicate_columns(A))
# [array([0, 4]), array([1, 2, 5])]