Python 在Numpy中将操作矢量化

Python 在Numpy中将操作矢量化,python,numpy,vectorization,Python,Numpy,Vectorization,我正在尝试在Numpy上执行以下操作,而不使用循环: 我有一个维数为N*d的矩阵X和一个维数为N的向量y。 y包含从1到K的整数 我试图得到一个大小为K*d的矩阵M,其中M[I,:]=np.mean(X[y==I,:],0) 我可以不使用循环来实现这一点吗 有了一个循环,它就会变成这样 import numpy as np N=3 d=3 K=2 X=np.eye(N) y=np.random.randint(1,K+1,N) M=np.zeros((K,d)) for i in n

我正在尝试在Numpy上执行以下操作,而不使用循环:

  • 我有一个维数为N*d的矩阵X和一个维数为N的向量y。 y包含从1到K的整数
  • 我试图得到一个大小为K*d的矩阵M,其中M[I,:]=np.mean(X[y==I,:],0)
我可以不使用循环来实现这一点吗

有了一个循环,它就会变成这样

import numpy as np

N=3
d=3 
K=2 

X=np.eye(N)
y=np.random.randint(1,K+1,N)
M=np.zeros((K,d))
for i in np.arange(0,K):
    line=X[y==i+1,:]
    if line.size==0:
        M[i,:]=np.zeros(d)
    else:
        M[i,:]=mp.mean(line,0)

提前谢谢。

这解决了问题,但是创建了一个中间的K×N布尔矩阵,并且没有使用内置的均值函数。在某些情况下,这可能会导致较差的性能或较差的数值稳定性。我让类标签的范围从
0
K-1
,而不是
1
K

# Define constants
K,N,d = 10,1000,3

# Sample data
Y = randint(0,K-1,N) #K-1 to omit one class to test no-examples case
X = randn(N,d)

# Calculate means for each class, vectorized 

# Map samples to labels by taking a logical "outer product"
mark = Y[None,:]==arange(0,K)[:,None] 

# Count number of examples in each class    
count = sum(mark,1)

# Avoid divide by zero if no examples
count += count==0

# Sum within each class and normalize
M = (dot(mark,X).T/count).T

print(M, shape(M), shape(mark))

代码基本上是从X中收集特定的行并添加它们,我们在其中内置了一个NumPy。因此,有了这个重点,以矢量化方式解决它的步骤可以如下所示-

# Get sort indices of y
sidx = y.argsort()

# Collect rows off X based on their IDs so that they come in consecutive order
Xr = X[np.arange(N)[sidx]]

# Get unique row IDs, start positions of each unique ID
# and their counts to be used for average calculations
unq,startidx,counts = np.unique((y-1)[sidx],return_index=True,return_counts=True)

# Add rows off Xr based on the slices signified by the start positions
vals = np.true_divide(np.add.reduceat(Xr,startidx,axis=0),counts[:,None])

# Setup output array and set row summed values into it at unique IDs row positions
out = np.zeros((K,d))
out[unq] = vals

K==N吗?y的值是唯一的吗?如果你展示一些代码,这会很酷。如果你把输入写成一个我们可以运行的短代码段,这会有所帮助,例如
y=np.random.random\u整数(低=1,高=K,大小=N)
X=?
并定义
K
N
等等。如果添加一些代码,用一个循环来计算输出,那么我们将非常清楚您想要实现的目标。在您的实际情况中,
X
也是一个单位矩阵还是它有随机数?类似于@Divakar的问题:因为您将
X
的元素与索引进行比较,一般来说,
X
可以包含什么?它的
dtype
是什么?谢谢你更新问题,现在更清楚了