我有一个列表(我们叫它all_my_arrays
)包含大约48,000个1D数组。我想知道此列表中有多少个重复数组(如果有)。但是,我想排除空数组(因为列表中有多个空数组,并且不希望将这些空数组计入我的重复计数中)。我在下面尝试了此代码,但是花费的时间太长:
import numpy as np
uniques=[]
for arr in all_my_arrays:
if not np.array_equal(np.array([]), arr):
if not any(np.array_equal(arr, unique_arr) for unique_arr in uniques):
uniques.append(arr)
print(len(uniques)) #number of non-duplicates
是否有更快的方法来完成此操作?
答案 0 :(得分:1)
您可以使用set
类型来获取列表中的唯一值。首先,您必须将数组转换为可哈希的类型(这里的元组很好)。这是一个示例:
uniques = set(tuple(arr) for arr in all_my_arrays if arr.size > 0)
集合uniques
将包含原始all_my_arrays
列表中的所有唯一的非空数组。 uniques
的内容是元组,但是您可以使用列表理解将它们转换回数组。如果您仅对唯一数组的数量感兴趣,则可以调用len(uniques)
,而不必担心转换回数组。
此方法的时间复杂度为O(n + m)
,其中n
是数组的数目,m
是数组的长度。但是,转换为元组会产生开销,但是我认为这种方法应该比您目前使用的方法(具有时间复杂性O(n^2)
)要快得多,尤其是对于如此大量的数组。
编辑:要使其更快一点,可以删除每个元素上的空支票,然后在末尾对其进行处理。如下所示:
uniques = set(tuple(arr) for arr in all_my_arrays)
num_unique = len(uniques) if () not in uniques else len(uniques) - 1
答案 1 :(得分:0)
这是一个基于NumPy的解决方案,可能对您有用。为简单起见,我将使用一个数组长度为3或0的示例。
请注意,按照您的定义,重复计数等于数组总数减空数组的数目减唯一非空数组的数目。
最后一部分可能是最昂贵的,但是我们可以在常规NumPy数组上使用np.unique
:
L = [np.array([1, 2, 3]), np.array([]), np.array([3, 2, 1]),
np.array([1, 3, 2]), np.array([1, 2, 3]), np.array([1, 3, 2]),
np.array([]), np.array([]), np.array([1, 2, 3])]
empty_arr = {idx for idx, arr in enumerate(L) if arr.shape == (0,)}
empty_count = len(empty_arr)
A = np.array([arr for idx, arr in enumerate(L) if idx not in empty_arr])
unique_arr = np.unique(A, axis=0)
duplicates = len(L) - len(empty_arr) - len(unique_arr)
print(duplicates) # 3
答案 2 :(得分:0)
我不确定自己是否完全了解您的问题。
不过,据我了解:
0
的数组; 如果正确,则可以执行以下操作:
import numpy as np
li_of_arr=[np.random.choice(4,7) for _ in range(50000)] # example list of arrays
mat=np.array([e for e in li_of_arr if np.any(e)]) # create a numpy matrix of non zero arrays
uniq=np.unique(mat,axis=0) # here are your unique sub arrays
print (len(mat), len(uniq)) # len of non zero elements and unique non zero elements
这在我的MacBook上花费不到1秒。
答案 3 :(得分:0)
只需
in_arr = np.array([i for i in all_my_arrays if i.size == 7])
uniques = np.unique(in_arr, axis = 0)
uniques_list = list(uniques) # if you really want a list
编辑:请注意np.unique
在内部进行排序,因此不会保留顺序。如果您想维持订单,则可能需要构建特殊的numba
函数。