我正在使用:x = pd.DataFrame(np.random.randint(0,10,size=(20, N)))
和N>5000
和y = np.random.dirichlet(np.ones(20),size=1)
。
我正在每个x
列和y
(这是权重列表,总和为1)之间执行矩阵乘积,最后得到N
个元素的数组,所以我使用x.T.dot(y)
。
现在,我想修改矩阵乘积的计算方式:对于X的当前列上的每个0,我们通过不考虑乘以0的权重来对y
进行加权。将其平均分配到权重之间,该权重将与不等于0的值相乘,因此列表的总和仍为1。
结构较小的示例
x
a1 a2 a3
b1 1 5 6
b2 3 0 0
b3 9 7 0
和y = [0.3, 0.5, 0.2]
预期输出:[3.6, 5.9, 6]
步骤1:没有零->简单加权平均值(0.3*1+0.5*3+0.2*9 = 3.6)
步骤2:(b2,a2) = 0
使y
变成[0.55, 0, 0.45]
和0.55*5+0.45*7 = 5.9
第3步:(b2,a3) & (b3,a3) = 0
,因此y
变成[1, 0, 0]
,总数为6。
特异性:构建数据帧的结构,例如当存在0时,同一行中的以下单元格将等于0。
答案 0 :(得分:1)
您可以通过堆叠A
来构建形状与y
相同的新矩阵,使用遮罩对其进行调整,然后对列进行元素明智的乘法和求和:
y= np.array([0.3, 0.5, 0.2])
A = np.array([[1, 5, 6],
[3, 0, 0],
[9, 7, 0]])
m = A == 0
new_y = np.repeat(y,A.shape[1]).reshape(A.shape)
new_y = (new_y + (new_y*m).sum(axis=0)/(~m).sum(axis=0))*~m
result = (new_y * A).sum(axis=0)
result
>> array([3.6 5.9 6. ])