Тензорное расширение в NumPy
Я пытаюсь найти элегантный способ решить следующую проблему.
У меня есть тензор y
содержащий n
dxd
матрицы, которые я получаю, выбирая комбинации строк матрицы X
, У меня есть второй массив NumPy размером k x d
, Мое намерение состоит в том, чтобы расширить тензор так, чтобы я добавил каждую из строк k x d
матрица для каждого из элементов в тензоре у, чтобы получить y'
тензор с k x n
d 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
в какой-то петле, но я не следил за этими деталями.