从NumPy 2D数组中删除重复的列和行
我正在使用一个二维数组来存储经度和纬度的配对。在某个时候,我需要把两个这样的二维数组合并在一起,然后去掉重复的条目。我一直在寻找一个类似于numpy.unique的函数,但一直没有找到。我想到的任何实现方式看起来都很“没效率”。比如,我尝试把数组转换成一个元组的列表,用集合去掉重复项,然后再转换回数组:
coordskeys = np.array(list(set([tuple(x) for x in coordskeys])))
有没有现成的解决方案,这样我就不用重新发明轮子了?
为了更清楚,我想要的是:
>>> a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
>>> unique_rows(a)
array([[1, 1], [2, 3],[5, 4]])
顺便说一下,我本来想只用元组的列表,但这些列表太大了,导致我的4GB内存加4GB交换空间都不够用(numpy数组更节省内存)。
6 个回答
5
我的方法是把一个二维数组转换成一个一维的复杂数组,其中实部是第一列,虚部是第二列。然后使用np.unique。不过这个方法只适用于有两列的情况。
import numpy as np
def unique2d(a):
x, y = a.T
b = x + y*1.0j
idx = np.unique(b,return_index=True)[1]
return a[idx]
举个例子 -
a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
unique2d(a)
array([[1, 1],
[2, 3],
[5, 4]])
33
这样做就可以解决问题:
def unique_rows(a):
a = np.ascontiguousarray(a)
unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))
举个例子:
>>> a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
>>> unique_rows(a)
array([[1, 1],
[2, 3],
[5, 4]])
16
这里有一个想法,虽然需要花一点时间去实现,但速度可能会很快。我先给你讲解一维数组的情况,然后你可以自己想办法把它扩展到二维。下面这个函数可以找到一维数组中的唯一元素:
import numpy as np
def unique(a):
a = np.sort(a)
b = np.diff(a)
b = np.r_[1, b]
return a[b != 0]
要把它扩展到二维,你需要改动两个地方。首先,你得自己想办法进行排序,排序的关键是要确保两个相同的元素能够排在一起。其次,你需要做类似于 (b != 0).all(axis)
的操作,因为你想要比较整行或整列的内容。如果这些信息能让你入门,那就太好了。
更新:在Doug的帮助下,我觉得这个方法应该可以适用于二维情况。
import numpy as np
def unique(a):
order = np.lexsort(a.T)
a = a[order]
diff = np.diff(a, axis=0)
ui = np.ones(len(a), 'bool')
ui[1:] = (diff != 0).any(axis=1)
return a[ui]