Внутри большого проекта мне нужно было определенным образом обработать 2D-массив. Первоначально я реализовал его с использованием четырехвложенного цикла for с тестом if, который проверяет, выполняется ли условие для заданных индексов. Ничего не должно произойти, если if-тест имеет значение False. Вот минимальный воспроизводимый пример:
import numpy as np
L=8; K=20
data = np.random.randint(-10,10,(L,K)) + np.random.randint(-10,10,(L,K))*1j
check_pos = data > 0
check_neg_imag = np.imag(data) < 0
def for_looped(data,L,K,check_pos,check_neg_imag):
processed = np.zeros((L,K,L,K), dtype=complex)
for l in range(L):
for k in range(K):
for ll in range(L):
for kk in range(K):
if (check_pos[l,k] and check_neg_imag[ll,kk]) or (check_neg_imag[l,k] and check_pos[ll,kk]):
processed[l,k,ll,kk] = data[l,k] * data[ll,kk].conj()
return processed
processed = for_looped(data,L,K,check_pos,check_neg_imag)
По мере увеличения размеров данных это происходит довольно медленно, поэтому я попытался векторизовать циклы for. Однако у меня возникли проблемы с if-тестом. Я пробовал просто векторизовать без него:
Это работает, но при этом тратится много вычислительного времени на вычисление значений, которые не используются. Я читал одно место, где np.where() можно использовать в сочетании с маской, например:
%timeit for_looped(data,L,K)
14.8 ms ± 44.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit vectorized(data)
45.5 µs ± 2.62 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit vectorized_where(data,mask)
65.9 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
Я подозреваю, что происходит то, что np.where() вычисляет data[:,:,None,None] * data[None,None,:,:]. conj() для всех индексов, а затем заменяет те, где маска имеет значение True, на 0. Это также тратит время вычислений на то, для чего я его использую.
Есть ли способ вычислить только data[:,:,None,None] * data[None,None,:,:].conj() для индексов, заданных маской?
Внутри большого проекта мне нужно было определенным образом обработать 2D-массив. Первоначально я реализовал его с использованием четырехвложенного цикла for с тестом if, который проверяет, выполняется ли условие для заданных индексов. Ничего не должно произойти, если if-тест имеет значение False. Вот минимальный воспроизводимый пример: [code]import numpy as np
L=8; K=20 data = np.random.randint(-10,10,(L,K)) + np.random.randint(-10,10,(L,K))*1j
check_pos = data > 0 check_neg_imag = np.imag(data) < 0
def for_looped(data,L,K,check_pos,check_neg_imag): processed = np.zeros((L,K,L,K), dtype=complex) for l in range(L): for k in range(K): for ll in range(L): for kk in range(K): if (check_pos[l,k] and check_neg_imag[ll,kk]) or (check_neg_imag[l,k] and check_pos[ll,kk]): processed[l,k,ll,kk] = data[l,k] * data[ll,kk].conj() return processed processed = for_looped(data,L,K,check_pos,check_neg_imag) [/code] По мере увеличения размеров данных это происходит довольно медленно, поэтому я попытался векторизовать циклы for. Однако у меня возникли проблемы с if-тестом. Я пробовал просто векторизовать без него: [code]def vectorized(data): return data[:,:,None,None] * data[None,None,:,:].conj() processed_vec = vectorized(data) [/code] Это работает, но при этом тратится много вычислительного времени на вычисление значений, которые не используются. Я читал одно место, где np.where() можно использовать в сочетании с маской, например: [code]mask = (check_pos[:,:,None,None] & check_neg_imag[None,None,:,:]) | (check_neg_imag[:,:,None,None] & check_pos[None,None,:,:]) def vectorized_where(data,mask): return np.where(mask, data[:,:,None,None] * data[None,None,:,:].conj(), 0) processed_vec_where = vectorized_where(data,mask) [/code] Однако я проверил время выполнения с помощью timeit, и код с np.where() на самом деле медленнее: [code]%timeit for_looped(data,L,K) 14.8 ms ± 44.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit vectorized(data) 45.5 µs ± 2.62 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit vectorized_where(data,mask) 65.9 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each) [/code] Я подозреваю, что происходит то, что np.where() вычисляет data[:,:,None,None] * data[None,None,:,:]. conj() для всех индексов, а затем заменяет те, где маска имеет значение True, на 0. Это также тратит время вычислений на то, для чего я его использую. Есть ли способ вычислить только data[:,:,None,None] * data[None,None,:,:].conj() для индексов, заданных маской?
У меня есть коллекция симметричных тензоров full_tensors, и я вычислил все отдельные элементы в двумерном массиве tensor_reduced. Я хочу вычислить полные full_tensors из отдельных элементов tensor_reduced. У меня есть список all_permutations_list,...
Проблема
У меня есть valid_data (1D np.array с ненулевыми значениями) и маска (логическое значение 1D np.array ), которые не одинакового размера. Маска содержит нужные позиции valid_data в новом создаваемом np.array. Могу ли я легко...
У меня есть массив target, скажем: . У меня есть еще один массив, который необходимо объединить (toMerge) с target, скажем: . У меня также есть целочисленный массив, который сообщает индексам целевого массива, где элементы *toMerge будут объединены,...
У меня есть массив target, скажем: . У меня есть еще один массив toMerge, который нужно объединить с target, скажем: . У меня также есть целочисленный массив, который сообщает индексам целевого массива, где элементы toMerge будут окончательно...
У меня есть массив target, скажем: . У меня есть еще один массив toMerge, который нужно объединить с target, скажем: . У меня также есть целочисленный массив, который сообщает индексам целевого массива, где элементы toMerge будут окончательно...