英文:
How can I vectorize the interaction of two numpy arrays
问题
你的代码目前是针对较小的数组有效的。要向量化这个操作,你可以使用NumPy的高级功能来提高效率。以下是一个向量化的示例代码:
import numpy as np
# 输入数组a和b
a = np.array([[1, 0, 4, 5, 2, 3],
[2, 3, 0, 1, 5, 4],
[3, 4, 5, 0, 1, 2],
[4, 5, 3, 2, 0, 1],
[5, 2, 1, 4, 3, 0]])
b = np.array([[0, 1, 3, -1],
[0, 2, -1, 3],
[0, 3, -2, 4],
[0, 4, -1, 0],
[0, 5, -1, 4],
[1, 2, 4, -3],
[1, 3, 0, -1],
[1, 4, 1, -2],
[1, 5, 1, 1],
[2, 3, 1, 1],
[2, 4, -1, 0],
[2, 5, -1, 1],
[3, 4, 0, 0],
[3, 5, 2, 1],
[4, 5, 1, -2]])
# 创建一个与a相同形状的零数组c
c = np.zeros_like(a)
# 遍历数组b,执行相应的操作
for row in b:
p, q, m1, m2 = row
c[:, p] += a[:, q] * m1
c[:, q] += a[:, p] * m2
# 打印结果数组c
print(c)
这个代码将对数组a和b进行向量化操作,生成与你所需的结果相符的数组c。
英文:
Consider two numpy arrays:
-
array
a
: The important feature of arraya
is that every pair of columns (p
andq
) has a row that holds values (q
andp
) in that order.
For example, columns 0 and 3 hold values 3 and 0 in row 2, and columns 4 and 5 hold values 5 and 4 in row 1.a = np.array([[1, 0, 4, 5, 2, 3], [2, 3, 0, 1, 5, 4], [3, 4, 5, 0, 1, 2], [4, 5, 3, 2, 0, 1], [5, 2, 1, 4, 3, 0]])
-
array
b
: The first two columns show ALL column pairs (p
andq
) from arraya
. The remaining two columns are multipliers, as shown in the following: Consider arrayb
's row 5[1, 2, 4, -3]
. We examine columns 1 and 2 of arraya
, and locate the values 2 and 1. Then we replace, in arraya
, the 2 by 2x4=8, and we replace the 1 by 1x(-3) = -3.b = np.array([[0, 1, 3 -1], [0, 2, -1, 3], [0, 3, -2, 4], [0, 4, -1, 0], [0, 5, -1, 4], [1, 2, 4, -3], [1, 3, 0, -1], [1, 4, 1, -2], [1, 5, 1, 1], [2, 3, 1, 1], [2, 4, -1, 0], [2, 5, -1, 1], [3, 4, 0, 0], [3, 5, 2, 1], [4, 5, 1, -2]])
The final result would look like:
c = np.array([[ 3, 0,-4,10, 0, 3],
[-2, 0, 0,-1, 5,-8],
[-6, 4,-5, 0,-2, 2],
[-4, 5, 3, 2, 0, 1],
[-5, 8,-3, 0, 0, 0]])
Here is what I've been using. It works well for smaller arrays (produces the array c shown above), but my coding skills are quite rusty:
c = np.copy(a)
for brow in b:
arow = np.where(a[:, brow[0]] == brow[1])
c[arow, brow[0]] = (a[arow, brow[0]])*brow[2]
c[arow, brow[1]] = (a[arow, brow[1]])*brow[3]
print(c)
Could this be vectorized?
答案1
得分: 1
这是一个需要升维度的解决方案。让我们将您的代码定义在一个函数中,以便比较性能。
def find_c(a, b):
c = np.copy(a)
for brow in b:
arow = np.where(a[:, brow[0]] == brow[1])
c[arow, brow[0]] = (a[arow, brow[0]]) * brow[2]
c[arow, brow[1]] = (a[arow, brow[1]]) * brow[3]
return c
以及我编写了一些注释来解释我的解决方案:
def find_c_1(a, b):
c = np.copy(a)
# 升维度以索引数据
array_find = a[:, None][:, 0, b[:, 0]].T
# 找到与b[:, 1]的值对应的索引
index = np.where(array_find == b[:, 1].reshape(-1, 1))
# index[1]是行的索引,b[:, 0]是列的索引
# 然后对值进行赋值
c[index[1], b[:, 0]] = c[index[1], b[:, 0]] * b[:, 2]
c[index[1], b[:, 1]] = c[index[1], b[:, 1]] * b[:, 3]
return c
用于比较结果的部分:
c1 = find_c(a, b)
c2 = find_c_1(a, b)
print(np.array_equal(c1, c2)) # True
用于比较性能的部分:
%timeit find_c(a, b)
314 µs ± 5.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit find_c_1(a, b)
23.8 µs ± 1.06 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
英文:
Here is a solution which needs dimensionality ascension. Let's define your codes in a function for comparing the performance.
def find_c(a, b):
c = np.copy(a)
for brow in b:
arow = np.where(a[:, brow[0]] == brow[1])
c[arow, brow[0]] = (a[arow, brow[0]])*brow[2]
c[arow, brow[1]] = (a[arow, brow[1]])*brow[3]
return c
And my solution which I wrote some comments for explaining :
def find_c_1(a, b):
c = np.copy(a)
# ascension for indexing the data
array_find = a[:, None][:, 0, b[:, 0]].T
# find the index corresponds the values of b[:, 1] in array
index = np.where(array_find == b[:, 1].reshape(-1, 1))
# index[1] is the index of rows , b[:, 0] is the index of columns
# Then the assignment of the values
c[index[1], b[:, 0]] = c[index[1], b[:, 0]] * b[:, 2]
c[index[1], b[:, 1]] = c[index[1], b[:, 1]] * b[:, 3]
return c
For comparing the result :
c1 = find_c(a, b)
c2 = find_c_1(a, b)
print(np.array_equal(c1, c2)) # True
For comparing the performance:
%timeit find_c(a, b)
314 µs ± 5.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit find_c_1(a, b)
23.8 µs ± 1.06 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论