Python 如何使用NumPy以矢量化方式通过二维阵列缩放一组二维阵列(三维阵列)?
我有一个3D矩阵,包含M个通道的N x N协方差矩阵[M x N x N]。在一系列时间点[M x T]上,我还有一个每个通道的二维比例因子矩阵。我想生成一个4D矩阵,其中包含每个时间点相关通道协方差的缩放版本。所以要说清楚,[M x T]*[M x N x N]->[M x T x N x N] 使用for循环的当前版本:Python 如何使用NumPy以矢量化方式通过二维阵列缩放一组二维阵列(三维阵列)?,python,arrays,numpy,vectorization,Python,Arrays,Numpy,Vectorization,我有一个3D矩阵,包含M个通道的N x N协方差矩阵[M x N x N]。在一系列时间点[M x T]上,我还有一个每个通道的二维比例因子矩阵。我想生成一个4D矩阵,其中包含每个时间点相关通道协方差的缩放版本。所以要说清楚,[M x T]*[M x N x N]->[M x T x N x N] 使用for循环的当前版本: m, t, n = 4, 10, 7 channel_timeseries = np.zeros((m, t)) covariances = np.random.rand(
m, t, n = 4, 10, 7
channel_timeseries = np.zeros((m, t))
covariances = np.random.rand(m, n, n)
result_array = np.zeros((m, t, n, n))
# Each channel
for i, (channel_cov, channel_timeseries) in enumerate(zip(covariances, channel_timeseries)):
# Each time point
for j, time_point in enumerate(channel_timeseries):
result_array[i, j] = time_point * channel_cov
这将导致结果数组全部为零。将信道时间序列的初始化替换为np.ones
,我们应该看到在时间序列的每个步骤中复制的每个信道的协方差不变
对我来说,真正重要的情况是,每个通道在每个时间点都有一个标量值,我们通过匹配正确通道和时间点的值来缩放相关通道的协方差矩阵
正如您在上面看到的,我可以使用for循环来实现这一点,它工作得非常好,但我正在使用一些大型数据集,最好使用矢量化解决方案
非常感谢您的时间。会在这里派上用场的。我已使用随机通道\u timeseries
数组修改了您的代码,增加了数组大小,并重命名了循环变量(否则将覆盖原始变量!)
这导致在我的机器中使用
numpy.einsum
时速度提高50%以上。您可以使用np.einsum
或广播:
channel_timeseries[:, :, None, None] * covariances[:, None, :, :]
谢谢你!我接受了尼尔斯的回答,因为他还建议采用广播方式,结果又快了一点。对于回路:142 ms±491µs/回路(平均值±标准偏差7次,每个回路10次)einsum:3.82 ms±44.3µs/回路(平均值±标准偏差7次,每个回路100次)广播:2.13 ms±7.39µs/回路(平均值±标准偏差7次,每个回路100次)我有兴趣看到广播方法比einsum快(einsum:3.82 ms±44.3µs/循环(平均值±标准偏差7次,每个循环100次)广播:2.13 ms±7.39µs/循环(平均值±标准偏差7次,每个循环100次)),因此我采用该解决方案。非常感谢!是的,通常(但并非总是)是这样。
np.einsum('mt,mno->mtno', channel_timeseries, covariances)
channel_timeseries[:, :, None, None] * covariances[:, None, :, :]