Как заполнить 4D матрицу 2D матрицей для каждого 2D сечения в Python

Итак, у меня есть матрица, которая называется Vjunk, 70х70х70х70. У меня есть другая матрица, которая является 70x70, назовите это V.

Что я хочу сделать, так это чтобы для каждого i, j матрица Vjunk[:,:,i,j] была 70 на 70. Я хочу изменить эту матрицу так, чтобы она заменялась самой собой + V[i,j], где V [i, j] - i-й элемент моей матрицы V.

Я попытался [Vjunk[:,:,i,j] = Vjunk[:,:,i,j] -бета *V[i,j] для i в диапазоне (humangrid_size) для j в диапазоне (assetgrid_size)]

но эта команда неуспешна.

1 ответ

Давайте использовать этот индекс на Vjunk: (m, n, i, j)

Если я прав, вы хотите, чтобы для каждой комбинации m, n Vjunk(m,n,i,j) заменялся на Vjunk(m,n,i,j) -бета * V[i,j]. Если это цель, этот цикл должен сделать свое дело:

for m in range(70):
    for n in range(70):
        for i in range(70):
            for j in range(70):
                Vjunk[m,n,i,j] = Vjunk[m,n,i,j] - beta * V[i,j]

Не знаю, будет ли это достаточно быстро, даже если это всего лишь матрица 70*70*70*70. Еще более 20 миллионов операций.

Цикл на i, j может быть заменен на понимание списка.

Во-первых, вы не можете помещать задания в список.

Во-вторых: вам повезло, потому что Vjunk а также Vлегко транслировать, когда вы их вычитаете. Вот пример с нетривиальными формами, чтобы упростить поиск ошибок:

import numpy as np

Vjunk = np.random.rand(2, 3, 4, 5) 
V = np.random.rand(4, 5) 

# naive version: loop
res1 = Vjunk.copy() 
for i in range(2): 
    for j in range(3): 
        for l in range(4): 
            for m in range(5): 
                res1[i,j,l,m] -= V[l,m]

# vectorized, broadcasting version:
res2 = Vjunk - V

print(np.array_equal(res1, res2))
# True

Вот Vjunk имеет форму (2, 3, 4, 5), а также V имеет форму (4, 5). Последний совместим с формой(1, 1, 4, 5) для целей трансляции, что в таком случае совместимо с формой Vjunk.

Выполнение широковещательного вычитания Vjunk - V будет делать то, что вы хотите: для каждого элемента по последним двум измерениям каждое значение Vjunk (2d-массив по первым двум измерениям) будет уменьшен на V.

Затем просто добавить скалярный множитель:

res = Vjunk - beta * V