Тензорное расширение в NumPy

Я пытаюсь найти элегантный способ решить следующую проблему.

У меня есть тензор y содержащий ndxd матрицы, которые я получаю, выбирая комбинации строк матрицы X, У меня есть второй массив NumPy размером k x d, Мое намерение состоит в том, чтобы расширить тензор так, чтобы я добавил каждую из строк k x d матрица для каждого из элементов в тензоре у, чтобы получить y' тензор с k x nd x (d+1) матрицы.

Я не вижу, как это сделать без цикла for. Мой простой пример кода выглядит следующим образом:

#Array x
X = np.arange(27).reshape(9,3)
# Create tensor y
combs = [(0,1,2),(0,1,3),(0,1,4),(0,1,5)]
y = X[combs,:]
# Add a dummy column of 1.0s to each element of the y tensor
b = np.array([1.0,1.0,1.0]).reshape(1,3)
b = b.repeat(y.shape[0],axis=0).reshape(y.shape[0],y.shape[1],1)
# Concatenate the column with the tensor
y_new = np.concatenate((y,b),axis=2)`

Это решение далеко от идеального, потому что мне нужно было бы сохранить копию исходного массива, перебрать все строки, получить k тензоры, а затем объединить их в конце. В общей задаче, которую я пытаюсь решить, тензоры y большие, и несколько процессов выполняются параллельно, поэтому это тензорное расширение в идеале должно быть максимально эффективным. Любые предложения приветствуются!

2 ответа

Решение

Я считаю, что следующий код делает то, что вам нужно, без циклов. Идея состоит в том, чтобы расширить тензоры до нужного измерения, а затем выполнить конкатенацию со значением numpy в одну строку:

X = np.arange(27).reshape(9,3)
# Create tensor y
combs = [(0,1,2),(0,1,3),(0,1,4),(0,1,5)]
y = X[combs,:]
# Create tensor b, (the k x d matrix in your question)
b = np.arange(100,121).reshape(7,3,1)
# expand the tensors 
b = np.stack([b]*4,axis=1)
y = np.stack([y]*7)
# concatenate
y_new = np.concatenate([y,b],axis=3) 

Ваш repeat а также concatenate код может быть упрощен и, возможно, ускорен:

In [50]: z = np.zeros((y.shape[:-1]+(y.shape[-1]+1,)))
In [51]: z.shape
Out[51]: (4, 3, 4)
In [52]: z[:,:,:-1]=y
In [53]: z[:,:,-1]=np.array([.1,.2,.3])

То есть создать целевой массив и заполнить значениями из y а также b, С трансляцией b не нужно менять форму и повторять

Звучит так, как будто вы встраиваете это y_new в какой-то петле, но я не следил за этими деталями.

Другие вопросы по тегам