numpy 中的张量展开
Tensor expansion in numpy
我正在尝试找到一种优雅的方法来解决以下问题。
我有一个包含 n
dxd
矩阵的张量 y
,我通过选择矩阵 X
的行组合获得它。我有第二个 numpy 数组,大小为 k x d
。我的目的是扩展张量,以便将 k x d
矩阵的每一行添加到 y 张量中的每个元素,以获得 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
很大并且多个进程并行执行,因此这种张量扩展理想情况下应该尽可能高效。任何建议表示赞赏!
您的 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
嵌入到某种循环中,但我没有遵循这些细节。
我相信以下代码可以在没有循环的情况下满足您的要求。这个想法是将张量扩展到所需的维度,然后在一行中与 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)
我正在尝试找到一种优雅的方法来解决以下问题。
我有一个包含 n
dxd
矩阵的张量 y
,我通过选择矩阵 X
的行组合获得它。我有第二个 numpy 数组,大小为 k x d
。我的目的是扩展张量,以便将 k x d
矩阵的每一行添加到 y 张量中的每个元素,以获得 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
很大并且多个进程并行执行,因此这种张量扩展理想情况下应该尽可能高效。任何建议表示赞赏!
您的 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
嵌入到某种循环中,但我没有遵循这些细节。
我相信以下代码可以在没有循环的情况下满足您的要求。这个想法是将张量扩展到所需的维度,然后在一行中与 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)