我正在尝试使用numpy矢量化操作。但我在以下任务中遇到了困难:设置是两个不同长度的数组(X1, X2)。我想对每一对应用一种方法(例如X1[0]与X2[0], X2[1]等)。我使用循环编写了下面的工作代码,但我想摆脱循环。
result = []
for i in range(len(X1)):
result.append([])
for j in range(len(X2)):
tmp = my_method(X1[i] - X2[j])
result[i].append(tmp)
result = np.asarray(result)
您可以将其中一个矢量reshape
设置为(N, 1)
,然后使用vectorize
将正常广播操作:
import numpy as np
X1 = np.arange(5)
X2 = np.arange(3)
print(X1, X2)
# [0 1 2 3 4] [0 1 2]
def my_op(x, y):
return x + y
np.vectorize(my_op)(X1[:, np.newaxis], X2)
# array([[0, 1, 2],
# [1, 2, 3],
# [2, 3, 4],
# [3, 4, 5],
# [4, 5, 6]])
注意my_op
只是一个例子;如果你的函数实际上是numpy的矢量化操作中包含的任何东西,那么直接使用它会快得多,例如:
X1[:, np.newaxis] + X2
itertools.product
可能就是你要找的:
from itertools import product
import numpy as np
x1 = np.array(...)
x2 = np.array(...)
result = np.array([my_method(x_1 - x_2) for x_1, x_2 in product(x1,x2)])
也可以使用双链表推导式:
result = np.array([my_method(x_1 - x_2) for x_1 in x1 for x_2 in x2])
这显然取决于my_method
正在做什么和操作什么,以及你在x1
和x2
中存储了什么。
假设一个简单的函数my_method(a, b)
,它将两个数字相加。
这个输入:
X1 = np.arange(10)
X2 = np.arange(10,60,10)
你的代码是:
result = []
for i in range(len(X1)):
result.append([])
for j in range(len(X2)):
tmp = my_method(X1[i], X2[j])
result[i].append(tmp)
result = np.asarray(result)
您可以将其替换为广播:
X1[:,None]+X2
输出:
array([[10, 20, 30, 40, 50],
[11, 21, 31, 41, 51],
[12, 22, 32, 42, 52],
[13, 23, 33, 43, 53],
[14, 24, 34, 44, 54],
[15, 25, 35, 45, 55],
[16, 26, 36, 46, 56],
[17, 27, 37, 47, 57],
[18, 28, 38, 48, 58],
[19, 29, 39, 49, 59]])
现在你需要看看你的操作是否可以矢量化…请分享你想要实现的细节。可以使用numpy.vectorize
对函数进行矢量化,但这不是一个神奇的工具,因为它会在元素上循环,这可能很慢。最好是有一个真正的向量操作。