Python 矢量化numpy索引并应用函数构建矩阵
我有一个大小为(d,N)的矩阵X。换句话说,有N个向量,每个向量都有d维。比如说,Python 矢量化numpy索引并应用函数构建矩阵,python,performance,numpy,vectorization,Python,Performance,Numpy,Vectorization,我有一个大小为(d,N)的矩阵X。换句话说,有N个向量,每个向量都有d维。比如说, X = [[1,2,3,4],[5,6,7,8]] I = [ [0,1], [1,2,3] ] 有N=4个向量d=2维 此外,我还有rag数组(列表列表)。索引是X矩阵中的索引列。比如说, X = [[1,2,3,4],[5,6,7,8]] I = [ [0,1], [1,2,3] ] I[0]=[0,1]索引矩阵X中的列0和1。类似地,元素I[1]索引列1,2和3。请注意,I的元素是长度不同的列表 我
X = [[1,2,3,4],[5,6,7,8]]
I = [ [0,1], [1,2,3] ]
有N=4个向量d=2维
此外,我还有rag数组(列表列表)。索引是X矩阵中的索引列。比如说,
X = [[1,2,3,4],[5,6,7,8]]
I = [ [0,1], [1,2,3] ]
I[0]=[0,1]索引矩阵X中的列0和1。类似地,元素I[1]索引列1,2和3。请注意,I的元素是长度不同的列表
我想做的是,使用I中的每个元素为矩阵X中的列编制索引,对向量求和,得到一个向量。对I的每个元素重复此操作,从而构建一个新的矩阵Y。矩阵Y应具有与I数组中元素相同的d维向量。在我的示例中,Y矩阵将有2个2维向量
在我的例子中,元素I[0]告诉我们从矩阵X中得到第0列和第1列。求矩阵X的两个向量和二维向量的和,然后把这个向量放到Y中(第0列)。然后,元素I[1]告诉我们对矩阵X的第1、2和3列求和,并将这个新向量放入Y(第1列)
我可以很容易地使用循环来实现这一点,但如果可能的话,我想将此操作矢量化。“我的矩阵X”有数十万列,“我的索引矩阵”有数万个元素(每个元素都是索引的简短列表)
我的循环代码:
Y = np.zeros( (d,len(I)) )
for i,idx in enumerate(I):
Y[:,i] = np.sum( X[:,idx], axis=1 )
这里有一个方法-
# Get a flattened version of indices
idx0 = np.concatenate(I)
# Get indices at which we need to do "intervaled-summation" along axis=1
cut_idx = np.append(0,map(len,I))[:-1].cumsum()
# Finally index into cols of array with flattend indices & perform summation
out = np.add.reduceat(X[:,idx0], cut_idx,axis=1)
循序渐进-
In [67]: X
Out[67]:
array([[ 1, 2, 3, 4],
[15, 6, 17, 8]])
In [68]: I
Out[68]: array([[0, 2, 3, 1], [2, 3, 1], [2, 3]], dtype=object)
In [69]: idx0 = np.concatenate(I)
In [70]: idx0 # Flattened indices
Out[70]: array([0, 2, 3, 1, 2, 3, 1, 2, 3])
In [71]: cut_idx = np.append(0,map(len,I))[:-1].cumsum()
In [72]: cut_idx # We need to do addition in intervals limited by these indices
Out[72]: array([0, 4, 7])
In [74]: X[:,idx0] # Select all of the indexed columns
Out[74]:
array([[ 1, 3, 4, 2, 3, 4, 2, 3, 4],
[15, 17, 8, 6, 17, 8, 6, 17, 8]])
In [75]: np.add.reduceat(X[:,idx0], cut_idx,axis=1)
Out[75]:
array([[10, 9, 7],
[46, 31, 25]])
如果已实现,请共享您的循环代码?@Divakar添加了我的循环代码谢谢!你介意简要解释一下每一行的作用吗(在我查找函数之前)?@Divakar,如果我想只返回最后一步中的值而不是求和,那么函数会是什么而不是
np.add.reduceat
。因此,对于OP的X
和I
示例,我希望得到输出:[[1,2],[6,7,8]