簡體   English   中英

如何使用 NumPy 通過 2D 數組以矢量化方式縮放一組 2D arrays(3D 數組)?

[英]How can I scale a set of 2D arrays (3D array) by a 2D array in a vectorized way using NumPy?

我有一個 3D 矩陣,其中包含 M 個通道 [M x N x N] 的 N x N 個協方差矩陣。 我還有一個在一系列時間點 [M x T] 的每個通道的縮放因子的 2D 矩陣。 我想生成一個 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, 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替換 channel_timeseries 的初始化,我們應該看到每個通道的協方差在時間序列的每一步都沒有改變。

對我來說真正重要的情況是每個通道在每個時間點都有一個標量值,我們通過匹配正確通道和時間點的值來縮放相關通道的協方差矩陣。

正如你在上面看到的,我可以用一個 for 循環來做到這一點,它工作得很好,但我正在處理一些巨大的數據集,最好有一個矢量化的解決方案。

非常感謝您的時間。

numpy.einsum將在這里派上用場。 我用隨機channel_timeseries數組修改了你的代碼,增加了 arrays 的大小,並重命名了循環變量(否則你會覆蓋原來的變量!)

import numpy as np
import time

m, t, n = 40, 100, 70
channel_timeseries = np.random.rand(m, t)
covariances = np.random.rand(m, n, n)

t0 = time.time()
result_array_1 = np.zeros((m, t, n, n))
# Each channel
for i, (c_cov, c_ts) in enumerate(zip(covariances, channel_timeseries)):
    # Each time point
    for j, time_point in enumerate(c_ts):
        result_array_1[i, j] = time_point * c_cov
t1 = time.time()
result_array_2 = np.einsum('ij,ikl->ijkl', channel_timeseries, covariances)
t2 = time.time()

print(np.array_equal(result_array_1, result_array_2)) # True
print('Time for result_array_1: ', t1-t0) # 0.07601261138916016
print('Time for result_array_2: ', t2-t1) # 0.02957916259765625

這導致我的機器中的numpy.einsum的速度提高了 50% 以上。

正如 b-fg 所說,您可以使用np.einsum

np.einsum('mt,mno->mtno', channel_timeseries, covariances)

或廣播:

channel_timeseries[:, :, None, None] * covariances[:, None, :, :]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM