我有一个普通的Python列表,其中包含(多维)numPy数组,它们具有相同的形状和相同数量的值。列表中的某些数组与早期的数组重复。
我遇到的问题是我要删除所有重复项,但数据类型为numPy数组的事实使这一点复杂化......
•我无法使用set(),因为numPy数组不可清除
•我无法在插入过程中检查重复项,因为数组是由函数批量生成的,并使用.extend()添加到列表中。
•numPy数组不能直接比较,而不需要使用numPy自己的函数之一,所以我不能只使用&#34;如果列表中的x&#34; ... <登记/>
•列表的内容需要在流程结束时保留numPy数组;我可以比较转换为嵌套列表的数组的副本,但我不能永久地将数组转换为直接的python列表。
有关如何有效删除重复项的任何建议吗?
答案 0 :(得分:3)
根据数据结构的不同,直接比较所有数组可能会更快,而不是找到一些散列数组的方法。该算法是O(n ^ 2),但每个单独的比较将比创建数组的字符串或python列表快得多。所以它取决于您需要检查的阵列数量。
例如
uniques = []
for arr in possible_duplicates:
if not any(numpy.array_equal(arr, unique_arr) for unique_arr in uniques):
uniques.append(arr)
答案 1 :(得分:2)
使用这里的解决方案:Most efficient property to hash for numpy array如果a是一个numpy数组,我们看到散列最适合a.tostring()。所以:
import numpy as np
arraylist = [np.array([1,2,3,4]), np.array([1,2,3,4]), np.array([1,3,2,4])]
L = {array.tostring(): array for array in arraylist}
L.values() # [array([1, 3, 2, 4]), array([1, 2, 3, 4])]
答案 2 :(得分:2)
以下是使用tuple
的一种方式:
>>> import numpy as np
>>> t = [np.asarray([1, 2, 3, 4]),
np.asarray([1, 2, 3, 4]),
np.asarray([1, 1, 3, 4])]
>>> map(np.asarray, set(map(tuple, t)))
[array([1, 1, 3, 4]), array([1, 2, 3, 4])]
如果您的数组是多维的,那么首先将它们展平为1-by-whatever数组,然后使用相同的想法,并在最后重塑它们:
def to_tuple(arr):
return tuple(arr.reshape((arr.size,)))
def from_tuple(tup, original_shape):
np.asarray(tup).reshape(original_shape)
示例:
In [64]: t = np.asarray([[[1,2,3],[4,5,6]],
[[1,1,3],[4,5,6]],
[[1,2,3],[4,5,6]]])
In [65]: map(lambda x: from_tuple(x, t[0].shape), set(map(to_tuple, t)))
Out[65]:
[array([[1, 2, 3],
[4, 5, 6]]),
array([[1, 1, 3],
[4, 5, 6]])]
另一种选择是在pandas.DataFrame
中创建一个ndarrays
(如果需要,通过重新整形将它们视为行),并使用pandas内置函数来统一行。
In [34]: t
Out[34]: [array([1, 2, 3, 4]), array([1, 2, 3, 4]), array([1, 1, 3, 4])]
In [35]: pandas.DataFrame(t).drop_duplicates().values
Out[35]:
array([[1, 2, 3, 4],
[1, 1, 3, 4]])
总的来说,我认为尝试使用tostring()
作为准哈希函数是一个坏主意,因为你需要更多的样板代码而不是我的方法,以防止某些内容的可能性在某些dict
中被分配了“哈希”键后,它们会发生变异。
如果考虑到数据的大小,重新整形和转换为tuple
的速度太慢,我的感觉是,这揭示了一个更基本的问题:应用程序的设计并不能满足需求(如重复数据删除)并试图将它们塞进一些在内存中运行的Python进程可能不是正确的方法。那时,我会停下来考虑像Cassandra这样的东西,它可以在浮点(或其他)数据的大型列(或多维数组)之上轻松构建数据库索引,这不是更合理的方法。