我有2个numpy数组,一个数组的形状为(2, 5, 10)
,另一个数组的形状为(2, 5, 10, 10)
。
我想要的乘法是[[x1[i][j] * x2[i][j] for j in range(5)] for i in range(2)]
它按预期工作,但速度很慢,我想直接乘以x1 * x2,但是numpy不喜欢这样。
是否有一个numpy方法可以在给定的轴上相乘?
我尝试了numpy.multiply,因为它说'axis'是ufunc'multiply'的无效关键字
x1 = np.arange(100).reshape((2, 5, 10))
x2 = np.arange(1000).reshape((2, 5, 10, 10))
x = [[x1[i][j] * x2[i][j] for j in range(5)] for i in range(2)] # slow method that works
x = np.multiply(x1, x2, axis=2) # What I'm looking for but doesn't work.
答案 0 :(得分:1)
一种方法是,假设您对x
类型为np.array
感到满意,那就是更好地利用NumPy broadcasting(请参阅@hpaulj的答案):
import numpy as np
x1 = np.arange((2 * 3 * 4)).reshape((2, 3, 4))
x2 = np.arange((2 * 3 * 4 * 4)).reshape((2, 3, 4, 4))
x = [[x1[i][j] * x2[i][j] for j in range(3)] for i in range(2)]) # slow method that works
# : using NumPy broadcasting
y = x1[:, :, None, :] * x2
np.all(np.array(x) == y)
# True
时间方向的加速度约为10倍:
%timeit np.array([[x1[i][j] * x2[i][j] for j in range(3)] for i in range(2)])
# 13.6 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit x1[:, :, None, :] * x2
# 1.4 µs ± 10.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
答案 1 :(得分:1)
[[x1[i][j] * x2[i][j] for j in range(5)] for i in range(2)]
也使用广播。
x1[i,j].shape # (10,)
x2[i,j].shape # (10,10)
要相乘,广播规则会添加一个维度:
(10,), (10,10) => (1,10), (10,10) => (10,10)
但是,如果您使用过x1[i,j,:,None]
,广播将会进行
(10,1), (10,10) => (10,10)
产生不同的数字。
@ norok2格式的区别在于:
x1[:, :, None, :] * x2
x1[:, :, :, None] * x2
如果x2
的形状为(2,5,8,10)或(2,5,10,8),则差异会更加明显。
答案 2 :(得分:0)
使用您的输入信息
x1.shape
(2, 5, 10)
x2.shape
(2, 5, 10, 10)
您可以使用np.tensordot沿任意轴相乘-只要它们的尺寸匹配即可。
x3 = np.tensordot(x1, x2, (1,1))
x3.shape
(2, 10, 2, 10, 10)
tensordot还允许您在多个轴上相乘和相加。例如,在这种情况下。
x4 = np.tensordot(x1,x2, ((0,1), (0,1)))
x4.shape
(10, 10, 10)
这里的参数((0,1),(0,1))分别指向x1和x2的轴。