У меня есть массив input_data формы (A, B, C) и массив ind формы (B,). Я хочу пройти через ось B и взять сумму элементов C [B [i]] и C [B [i] +1]. Желаемый выход имеет форму (A, B). У меня есть следующий код, который работает, но я чувствую, что он неэффективен из-за циклизации по индексу через ось B. Есть ли более эффективный метод?Индексирование NumPy с переменным положением
import numpy as np
input_data = np.random.rand(2, 6, 10)
ind = [ 2, 3, 5, 6, 5, 4 ]
out = np.zeros((input_data.shape[0], input_data.shape[1]))
for i in range(len(ind)):
d = input_data[:, i, ind[i]:ind[i]+2]
out[:, i] = np.sum(d, axis = 1)
Edited на основе ответа Divakar в:
import timeit
import numpy as np
N = 1000
input_data = np.random.rand(10, N, 5000)
ind = (4999 * np.random.rand(N)).astype(np.int)
def test_1(): # Old loop-based method
out = np.zeros((input_data.shape[0], input_data.shape[1]))
for i in range(len(ind)):
d = input_data[:, i, ind[i]:ind[i]+2]
out[:, i] = np.sum(d, axis = 1)
return out
def test_2():
extent = 2 # Comes from 2 in "ind[i]:ind[i]+2"
m,n,r = input_data.shape
idx = (np.arange(n)*r + ind)[:,None] + np.arange(extent)
out1 = input_data.reshape(m,-1)[:,idx].reshape(m,n,-1).sum(2)
return out1
print timeit.timeit(stmt = test_1, number = 1000)
print timeit.timeit(stmt = test_2, number = 1000)
print np.all(test_1() == test_2(), keepdims = True)
>> 7.70429363482
>> 0.392034666757
>> [[ True]]
Спасибо, любезно! Я отредактировал вопрос, основываясь на вашем ответе. –
@StewartHolmes Lovely! Вы также можете попробовать второй подход, который предполагает степень как '2'. – Divakar