我有两个2D数组,例如
A = [[1,0],[2,0],[3,0],[4,0]]
B = [[2,0.3],[4,0.1]]
尽管数组要大得多,A的大小约为B的10倍,A的大约是100,000行。我想在行的第一个元素匹配时用A中的行替换A中的行,并保留A中的其他行未更改。在上面的例子中,我想最终得到:
[[1,0],[2,0.3],[3,0],[4,0.1]]
我该如何做到这一点,最好是有效率?
答案 0 :(得分:1)
在任何情况下,我们都必须迭代整个数组A,因为我们正在改变它。我们可以加速的是,如果A中特定的第一个元素存在于B中则查找。为此,用B创建字典会很有效。这样,查找将是恒定时间。我在这里假设A的第一个元素只匹配B的一个元素。
将B转换为dict可以这样做:
transformed_B = { item[0]: item[1] for item in B}
替换A中的元素可以通过以下方式完成:
transformed_A = [[item[0], transformed_B[item[0]]] if item[0] in transformed_B else item for item in A]
答案 1 :(得分:1)
另一种选择是对最小的数组进行排序,并使用二进制搜索来查找匹配的值。您可以采用矢量化方式执行此操作,如下所示:
a = np.zeros((1000, 2))
b = np.zeros((100, 2))
a[:, 0] =np.random.randint(200, size=(1000,))
b[:, 0] = np.random.choice(np.arange(100), size=(100,), replace=False)
b[: ,1] = np.random.rand(100)
# sort and binary search
b_sort = b[np.argsort(b[:, 0])]
idx = np.searchsorted(b_sort[:, 0], a[:, 0])
# don't look at indices larger than largest possible in b_sort
mask = idx < b.shape[0]
# check whether the value at the returned index really is the same
mask[mask] &= b_sort[idx[mask], 0] == a[:, 0][mask]
# copy the second column for positions fulfilling both conditions
a[:, 1][mask] = b_sort[idx[mask] ,1]
# only values < 100 should have a second column != 0
>>> a
array([[ 7.40000000e+01, 5.38114946e-01],
[ 8.80000000e+01, 9.21309165e-01],
[ 8.60000000e+01, 1.86336715e-01],
...,
[ 1.88000000e+02, 0.00000000e+00],
[ 5.00000000e+00, 3.81152557e-01],
[ 1.38000000e+02, 0.00000000e+00]]
)