我有两个数组arr1
和arr2
,大小分别为(90000,1)
和(120000,1)
。我想了解axis=0
上是否存在arr1
的{{1}}的任何元素。然后将它们的位置写到列表中,然后将其删除。这将确保两个列表中的任何一个都找不到。现在,我正在使用arr2
循环:
for
它在外部循环上使用list_conflict=[]
for i in range (len(arr1)):
for j in range (len(arr2)):
if (arr1[i]==arr2[j]):
list_conflict.append([i,j])
fault_index_pos = np.unique([x[0] for x in list_conflict])
fault_index_neg = np.unique([x[1] for x in list_conflict])
X_neg = np.delete(X_neg,fault_index_neg,axis=0)
X_pos = np.delete(X_pos,fault_index_pos,axis=0)
的元素,并将其与arr1
的每个元素进行详尽比较。如果找到匹配项,则将索引arr2
附加在第一个元素list_conflict
的位置和第二个arr1
的位置。然后将arr2
和fault_index_pos
压缩为唯一元素,因为fault_index_neg
的元素可能位于arr1
的多个位置,并且列表将具有重复位置。最后,通过将arr2
列表作为要删除的索引,用np.delete
删除匹配的元素。
我正在寻找一种更快的冲突比较方法,称为fault_index
,multiprocessing
或其他任何方法。您可以说不会花很多时间,但是实际上数组是在vectorization
维度中,但是为了清楚起见,我将它们缩短了。
答案 0 :(得分:3)
忽略numpy部分,找到冲突的索引对可以在纯Python中更快地完成,花费的时间与len(a)
加len(b)
和冲突数量成正比,而不是嵌套循环与向量长度的乘积成正比的时间:
def conflicts(a, b):
from collections import defaultdict
elt2ix = defaultdict(list)
for i, elt in enumerate(a):
elt2ix[elt].append(i)
for j, elt in enumerate(b):
if elt in elt2ix:
for i in elt2ix[elt]:
yield i, j
然后,例如
for pair in conflicts([1, 2, 4, 5, 2], [2, 3, 8, 4]):
print(pair)
显示
(1, 0)
(4, 0)
(2, 3)
是2和4匹配项的索引。
答案 1 :(得分:1)
import numpy as np
import pandas as pd
# create test data
np.random.seed(1)
a = np.random.randint(10, size=(10, 1))
np.random.seed(1)
b = np.random.randint(8, 15, size=(10, 1))
# create dataframe
df_a = pd.DataFrame(a)
df_b = pd.DataFrame(b)
# find unique values in df_a
unique_a = df_a[0].unique().tolist()
# create a Boolean mask and return only values of df_b not found in df_a
values_not_in_a = df_b[~df_b[0].isin(unique_a)].to_numpy()
a = array([[5],
[8],
[9],
[5],
[0],
[0],
[1],
[7],
[6],
[9]])
b = array([[13],
[11],
[12],
[ 8],
[ 9],
[11],
[13],
[ 8],
[ 8],
[ 9]])
# final output array
values_not_in_a = array([[13],
[11],
[12],
[11],
[13]])
import numpy
# create test data
np.random.seed(1)
a = np.random.randint(10, size=(10, 1))
np.random.seed(1)
b = np.random.randint(8, 15, size=(10, 1))
ua = np.unique(a) # unique values of a
ub = np.unique(b) # unique values of b
mask_b = np.isin(b, ua, invert=True)
mask_a = np.isin(a, ub, invert=True)
b_values_not_in_a = b[mask_b]
a_values_not_in_b = a[mask_a]
# b_values_not_in_a
array([13, 11, 12, 11, 13])
# a_values_not_in_b
array([5, 5, 0, 0, 1, 7, 6])
timeit
# using the following arrays
np.random.seed(1)
a = np.random.randint(10, size=(90000, 1))
np.random.seed(1)
b = np.random.randint(8, 15, size=(120000, 1))
%%timeit
5.6 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 2 :(得分:0)
请完成一些有关NumPy的向量功能以及Python的序列包含运算符的教程。您正在尝试编写一个大型应用程序,该应用程序非常需要您尚未学习的语言功能。
也就是说,也许最快的方法是将每个转换为set
并采用设置的交集。涉及的操作为 N 个元素的序列/集合的 O(n);您的嵌套循环为 O(N * M)(两个序列大小)。
任何有关Python集的教程都将引导您完成这一过程。
答案 3 :(得分:0)
如@Prune所建议,这是一个使用set
s的解决方案:
overlap = np.array(list(set(arr1) & set(arr2))) # Depending on array shapes you may need to flatten or slice first
arr1 = arr1[~np.isin(arr1, overlap)]
arr2 = arr2[~np.isin(arr2, overlap)]