【问题标题】:Getting the indexes to the duplicate columns of a numpy array [duplicate]获取numpy数组的重复列的索引[重复]
【发布时间】:2014-02-19 17:51:06
【问题描述】:

我有一个带有重复列的 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

但我无法从那里找出索引。

【问题讨论】:

  • 你需要numpy的性能,还是纯python实现OK?
  • 你已经接近了,你已经找到了所有独特的列。每个 True 值都是一个新组的起点。 ind 有你想要的所有索引,但是通过索引 ind 你只是取一个值而不是全部。尝试在连续 True 之间取 ind 中的所有值。
  • 谢谢大家。我认为那会做。我是 Python 新手;我来自 C++ 老派,我发现在 Python 中处理索引是不自然的。我使用 numpy 是因为我的数组非常大 [300000, 1000]

标签: python arrays numpy


【解决方案1】:

不幸的是,没有一种简单的方法可以做到这一点。使用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

【讨论】:

  • 有一个简单的方法来做到这一点。
  • @BiRico 那么请展示它而不是给出模糊的提示。另外,对于大量行,我没有看到 lexsort 比 unique 更快。
  • 如果你愿意,可以随意实现它,我现在没有我的电脑来写它并测试它。
  • +1 我们进行了 lexsort 与 void dtype 的讨论 here。我更喜欢这种方法,而且我想我当时就计时了,而且效果也更好,尤其是对于很长的列。
  • @Jamie 也许是时候考虑在 numpy 本身中实现它了。另外,我完全忘记了我不久前回答了完全相同的问题。
【解决方案2】:

这里概述了如何处理它。使用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])]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    相关资源
    最近更新 更多