numpy 如何计算矩阵的行的加权平均值,但每行的权重不同?

0s7z1bwu  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(150)

正如标题所暗示的,我有一个numpy矩阵(2d数组),它恰好是对称的,对角线上有0。我想使用np.average方法,以便将其行折叠成加权平均值的一维列数组,使用来自矩阵行的相同长度的权重数组。然而,由于对角线为零是有理由的,所以我不想在行的加权平均结果中计算它。换句话说,我希望每行都有一组不同的权重,这样对于第i行,对应的权重[i]将为零,其余的权重将保持不变。
有没有可能在没有显式循环的情况下做到这一点?
做这件事的最好方法是什么?
代码示例-

生成矩阵和权重:

mat = np.array([[       0,     2436,     2434,     2428,     2416],
                [    2436,        0,     2454,     2446,     2435],
                [    2434,     2454,        0,     2447,     2436],
                [    2428,     2446,     2447,        0,     2428],
                [    2416,     2435,     2436,     2428,        0]])
weights = np.array([262140,   196608,   196608, 196608, 196608])

当前(错误)实现:

计算加权平均值:

weighted_avg = np.average(mat, axis=-1, weights=weights)
print(weighted_avg)

Out: [1821.38194802 1984.31077694 1984.18578409 1979.68578982 1972.56080841]

循环实现:

weighted_avg = []
for i in range(mat.shape[0]):
    curr_weights = weights.copy()
    curr_weights[i] = 0
    weighted_avg.append(np.average(mat[i], axis=-1, weights=curr_weights))

weighted_avg = np.array(weighted_avg)
print(weighted_avg)

Out: [2428.5        2442.23079848 2442.076961   2436.53850163 2427.76928603]

我如何使用'proper numpy'使这个循环实现工作?

rkue9o1l

rkue9o1l1#

这可以通过这种向量化的方式来完成:

wr = np.repeat(weights[None,:], repeats=mat.shape[0],axis=0) 
# expand weights array to match the shape of mat array
# fill the diagonal with 0
np.fill_diagonal(wght_repeat, 0)
wght_avg = np.average(mat, axis=-1, weights = wr)
print(wght_avg)
>>array([2428.5       , 2442.23079848, 2442.076961  , 2436.53850163,
   2427.76928603])
holgip5t

holgip5t2#

我想我找到了解决这个问题的办法。如果有人能同意,那就太好了,但它似乎很有效:

# Create a matrix of shape (mat.shape[0], mat.shape[1]) where each row is a copy of `weights`
all_weights = np.tile(weights, (mat.shape[0], 1))

# Set the diagonal elements to zero
np.fill_diagonal(all_weights, 0)

# Calculate the weighted average along the last axis (-1) using `all_weights`
weighted_avg = np.average(mat, axis=-1, weights=all_weights)
print(weighted_avg)

Out: [2428.5        2442.23079848 2442.076961   2436.53850163 2427.76928603]

相关问题