【问题标题】:remove duplicate elements from two numpy arrays从两个numpy数组中删除重复元素
【发布时间】:2016-07-13 22:33:29
【问题描述】:

我有两个 numpy 数组 ab,有两千万个元素(浮点数)。如果这两个数组的组合元素相同,那么我们称之为重复,应该从两个数组中删除。例如,

a = numpy.array([1,3,6,3,7,8,3,2,9,10,14,6])
b = numpy.array([2,4,15,4,7,9,2,2,0,11,4,15])

从这两个数组中,我们有a[2]&b[2]a[11]&b[11] 相同,那么我们称之为重复元素,应该删除它。同a[1]&b[1] vs a[3]&b[3]虽然每个数组本身都有重复元素,但它们不被视为重复元素。所以我希望返回的数组是:

a = numpy.array([1,3,6,7,8,3,2,9,10,14])
b = numpy.array([2,4,15,7,9,2,2,0,11,4])

谁有最聪明的方法来实现这种减少?

【问题讨论】:

  • b[a!=b]a[a!=b] 会起作用吗?
  • 我试过了,它没有按预期工作。
  • 啊,误读了问题,np.vstack({tuple(row) for row in np.column_stack((a,b))}) 应该可以工作,可能不会给出您的第一个唯一元素顺序。
  • 我不知道它的成本是多少,但是你能不能像np.vstack((a,b)).T那样把它们做成一个数组,然后用this answer来查找唯一的行?

标签: python arrays numpy duplicates


【解决方案1】:

首先,您必须打包 ab 以识别重复项。 如果值是正整数(参见其他情况下的编辑),这可以通过以下方式实现:

base=a.max()+1
c=a+base*b

然后在c中找到唯一值:

val,ind=np.unique(c,return_index=True)

并检索ab 中的关联值。

ind.sort()
print(a[ind])
print(b[ind])

对于重复的disparition。 (这里有两个):

[ 1  3  6  7  8  3  2  9 10 14]
[ 2  4 15  7  9  2  2  0 11  4]

编辑

无论数据类型如何,c 数组都可以如下制作,将数据打包成字节:

ab=ascontiguousarray(vstack((a,b)).T) 
dtype = 'S'+str(2*a.itemsize)
c=ab.view(dtype=dtype)

【讨论】:

  • 谢谢。数组值为正数,但为浮点数。
  • 我提供了一个更通用的方法。
  • 非常感谢。有用。你的代码很简洁,但是不容易搞定~~~
  • 如果我想扩展到3个数组,我唯一需要改变的是np.vstack,对吧?我需要ab = np.vstack((a,b)), abc = np.ascontiguousarray(np.vstack((ab,c)).T),那么其余的都一样吧?
【解决方案2】:

这是一次性完成的,结果数组不需要任何额外的内存。

将每个索引处的元素配对并迭代它们。跟踪到目前为止已看到哪些对以及数组索引的计数器。当以前没有见过新的一对时,索引将增加 1,有效地将它们写回原来的位置。但是,对于重复的对,您不会增加索引,而是将每个新对有效地向左移动一个位置。最后,保留第一个indexth 个元素以缩短数组。

import itertools as it

def delete_duplicate_pairs(*arrays):
    unique = set()
    arrays = list(arrays)
    n = range(len(arrays))
    index = 0
    for pair in it.izip(*arrays):
        if pair not in unique:
            unique.add(pair)
            for i in n:
                arrays[i][index] = pair[i]
            index += 1
    return [a[:index] for a in arrays]

如果您使用的是 Python 2,zip() 会预先创建对列表。如果您的数组中有很多元素,使用itertools.izip() 会更有效,它将根据您的请求创建对。但是,Python 3 中的zip() 默认情况下是这样的。

对于你的情况,

>>> import numpy as np
>>> a = np.array([1,3,6,3,7,8,3,2,9,10,14,6])
>>> b = np.array([2,4,15,4,7,9,2,2,0,11,4,15])
>>> a, b = delete_duplicate_pairs(a, b)
>>> a
array([ 1,  3,  6,  7,  8,  3,  2,  9, 10, 14])
>>> b
array([ 2,  4, 15,  7,  9,  2,  2,  0, 11,  4])

现在,一切都取决于您的数组所包含的值。如果您只有值 0-9,则只有 100 个唯一对,并且大多数元素将是重复的,这样可以节省您的时间。对于 ab 的 2000 万个元素并且只包含 0-9 之间的值,该过程在 6 秒内完成。对于 0-999 之间的值,需要 12 秒。

【讨论】:

  • 非常感谢,我会试试的。但我忘了提一下,我拥有的两个数组包含介于 0 到 50 之间的浮点数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 2013-05-20
  • 2011-07-03
相关资源
最近更新 更多