#python #numpy
#python #numpy
Вопрос:
Изначально у меня было что-то вроде этого:
a = 1 # Some randomly generated positive integer
b = -1 # Some randomly generated negative integer
c = 0 # Constant 0
i = 0 # Randomly picked from (0, 1, 2)
d = [a, b, c][i]
Я хотел бы векторизовать это так, чтобы можно было генерировать много выборок
Итак, у меня есть три массива длиной N, индексный массив длиной N, и я хотел бы использовать этот индексный массив для выбора одного из трех массивов
a = np.array([1, 2, 3, 4])
b = np.array([-1, -2, -3, -4])
c = np.array([0, 0, 0, 0])
i = np.array([2, 1, 2, 0])
d = np.array([a, b, c])[i] # Doesn't work
# Would like the result:
d = np.array([0, -2, 0, 4])
d = a * (i == 0) b * (i == 1) c * (i == 2)
работает, но наверняка есть способ, который больше похож на невекторизованный код
Ответ №1:
Создайте 2-d массив из трех массивов, затем используйте целочисленное индексирование
>>> e = np.vstack([a,b,c])
>>> i = np.array([2, 1, 2, 0])
>>> e[(i,np.arange(i.shape[0]))]
array([ 0, -2, 0, 4])
>>>
Комментарии:
1. В моем исходном коде есть
size
параметр, который может бытьNone
для невекторизованной версии, на которую это можно легко расширитьnp.vstack([a, b, c])[(i, 0 if size is None else np.arange(size))]
. Спасибо! (Хотя это не распространяется наsize=[shape_0, shape_1]
)2. @frankden —
size=[shape_0, shape_1]
— в результате получается три 2-d массива?
Ответ №2:
Обратите внимание, что ваш ответ находится по диагонали
np.array([a, b, c])[i]
итак, вы можете перейти:
np.array([a, b, c])[i].diagonal()