英文:
How to calculate the weighted average of the rows of a matrix, but with different weights per row?
问题
根据您的请求,以下是翻译好的代码部分:
# 生成矩阵和权重数组
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)
# 循环实现:
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)
请注意,以上是代码的翻译,没有其他内容。
英文:
As the title implies, I have a numpy matrix (2d array) that happens to be symmetric with 0s in its diagonal.
I wanted to use the np.average method in order to collapse its rows into a 1d column array of weighted averages using a weight array from the same length of the rows of the matrix.
However, since the diagonals are zeros for a justified reason, I don't want to count it in the result of the row's weighted average.
In other words, I want a varying set of weights for each row, such that for the row i the corresponding weight[i] will be zero and the rest of the weights will remain the same.
Is it possible to do this without an explicit loop?
What is the best way to do it?
Code example-
Generate the matrix and the weights:
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])
Current (wrong) implementation:
Calculate the weighted average:
weighted_avg = np.average(mat, axis=-1, weights=weights)
print(weighted_avg)
Out: [1821.38194802 1984.31077694 1984.18578409 1979.68578982 1972.56080841]
Loop implementation:
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]
How can I make this loop implementation work using 'proper numpy'?
答案1
得分: 1
创建一个形状为(mat.shape[0],mat.shape[1])的矩阵,其中每一行都是weights
的副本
all_weights = np.tile(weights, (mat.shape[0], 1))
将对角线元素设为零
np.fill_diagonal(all_weights, 0)
使用all_weights
沿着最后一个轴(-1)计算加权平均值
weighted_avg = np.average(mat, axis=-1, weights=all_weights)
print(weighted_avg)
输出:[2428.5 2442.23079848 2442.076961 2436.53850163 2427.76928603]
英文:
I think I found a solution to this question. Would be great if someone could approve but it seems to work:
# 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]
答案2
得分: 1
这可以通过以下向量化方式完成:
wr = np.repeat(weights[None,:], repeats=mat.shape[0],axis=0)
# 将权重数组扩展以匹配矩阵数组的形状
# 将对角线填充为0
np.fill_diagonal(wr, 0)
wght_avg = np.average(mat, axis=-1, weights=wr)
print(wght_avg)
# >>array([2428.5 , 2442.23079848, 2442.076961 , 2436.53850163,
# 2427.76928603])
英文:
This can be done in this vectorized way:
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])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论