我有3个矩阵(np数组):
A是形状(n,m); B的形状为(m,k); C的形状为(n,k)
矩阵C只有集合{-1,0,1}中的值,它是"指示符"某种类型:如果C [i,j] == 1那么我想将第i行添加到b的第j列;如果C [i,j] ==( - 1)则减去(0不做任何事)。
可以很容易地使用循环来完成,但我想知道是否有一种矢量化的方法可以更快?
示例代码:
C = np.array([[-1, 0, 0, 0, 1],
[ 0, 0, 0, 0, -1],
[ 0, 0, 0, 0, -1],
[-1, 0, 0, 1, 1]])
a,b = np.where(C==1)
#here a=[0,3,3] and b=[4,3,4]
A[a,:] = [[0, 1, 2, 3, 4, 5, 6],
[3, 3, 3, 3, 3, 3, 3],
[3, 3, 3, 3, 3, 3, 3]]
B[:,b] += A[a] #B is all 0.0 before
预期结果:
array([[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 4.],
[ 0., 0., 0., 3., 5.],
[ 0., 0., 0., 3., 6.],
[ 0., 0., 0., 3., 7.],
[ 0., 0., 0., 3., 8.],
[ 0., 0., 0., 3., 9.]])
实际结果:
array([[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.],
[ 0., 0., 0., 3., 3.]])
答案 0 :(得分:2)
我们可以在np.add.at
-
B
np.add.at(B.T, b, A[a])
示例运行 -
In [39]: C = np.array([[-1, 0, 0, 0, 1],
...: [ 0, 0, 0, 0, -1],
...: [ 0, 0, 0, 0, -1],
...: [-1, 0, 0, 1, 1]])
...: a,b = np.where(C==1)
...: A = np.zeros((4,7),dtype=int)
...: A[a,:] = np.array([[0, 1, 2, 3, 4, 5, 6],
...: [3, 3, 3, 3, 3, 3, 3],
...: [3, 3, 3, 3, 3, 3, 3]])
In [40]: # Initialize B
...: B = np.zeros((7,5),dtype=int)
In [41]: np.add.at(B.T, b, A[a])
In [42]: B
Out[42]:
array([[0, 0, 0, 3, 3],
[0, 0, 0, 3, 4],
[0, 0, 0, 3, 5],
[0, 0, 0, 3, 6],
[0, 0, 0, 3, 7],
[0, 0, 0, 3, 8],
[0, 0, 0, 3, 9]])
作为commented by @DSM
,我们也可以使用矩阵 - 多重复制,从而避免获取C==1
的索引的步骤 -
A.T.dot(C==1)
答案 1 :(得分:1)
我把这一切都记在脑子里有点麻烦,但我相信这就是你要做的事情:
import numpy as np
n, m, k = 2, 3, 4
# A is full of 1s
A = np.ones((n,m))
# B is full of 0s
B = np.zeros((m,k))
# C is... that
C = np.array([
[ 0, 0, -1, 1],
[ 0, -1, 1, 0]
])
# Where to add A to B
add_x, add_y = np.where(C==1)
# Where to subtract A to B
sub_x, sub_y = np.where(C==-1)
# Select columns of B and += rows of A
# (using .T to transpose A so it's the same shape)
B[:,add_y] += A[add_x,:].T
# ditto thing above, but for -=
B[:,sub_y] -= A[sub_x,:].T
print(B)
输出:
[[ 0. -1. 0. 1.]
[ 0. -1. 0. 1.]
[ 0. -1. 0. 1.]]