如何使numpy数组每列总和为1

17

我正在构建用于实施PageRank算法的转移矩阵。如何使用numpy确保列之和为1。

例如:

1 1 1   
1 1 1  
1 1 1

应该被规范化为

.33 .33 .33  
.33 .33 .33  
.33 .33 .33
2个回答

30

将每列元素除以它们的列总和 -

a/a.sum(axis=0,keepdims=1) # or simply : a/a.sum(0)

为使行总和为1,更改轴输入 -

a/a.sum(axis=1,keepdims=1)

样例运行 -

In [78]: a = np.random.rand(4,5)

In [79]: a
Out[79]: 
array([[ 0.37,  0.74,  0.36,  0.41,  0.44],
       [ 0.51,  0.86,  0.91,  0.03,  0.76],
       [ 0.56,  0.46,  0.01,  0.86,  0.38],
       [ 0.72,  0.66,  0.56,  0.84,  0.69]])

In [80]: b = a/a.sum(axis=0,keepdims=1)

In [81]: b.sum(0) # Verify
Out[81]: array([ 1.,  1.,  1.,  1.,  1.])

为了确保它也适用于Python 2.x的int数组,请使用from __future__ import division或使用np.true_divide


对于列相加等于0的情况

对于列相加等于0的情况,假设我们可以将它们保留不变,我们可以将它们的总和设置为1,而不是除以0,如下所示 -

sums = a.sum(axis=0,keepdims=1); 
sums[sums==0] = 1
out = a/sums

列总和为零时失败。 - grofte
@grofte 根据问题描述,我们需要使得每一列的总和等于1。因此,对于总和恰好为0的列,我不知道该如何将它们转换成总和为1。 - Divakar
但是OP正在进行PageRank实现。您可以拥有不指向任何内容的节点。当发生这种情况时,它们需要在每个列的值中具有1/n。 - grofte
@grofte,你的意思是说,加起来等于0的列应该保持不变。也就是说,加起来等于0而不必担心加起来等于1?我认为OP应该对此进行限定。 - Divakar
好的。这是一篇关于PageRank的文章:https://www.rose-hulman.edu/~bryan/googleFinalVersionFixed.pdf - grofte
@ grofte 看起来是一篇信息丰富的文章,虽然我没有时间阅读。在这篇文章中进行了编辑,以处理该情况并不更改列元素。 - Divakar

-2
for i in range(len(A[0])):
    col_sum = A[:, i].sum()
    if col_sum != 0:
        A[:, i] = A[:, i]/col_sum
    else: 
        pass

for循环有点笨拙,我相信有更加优雅的方法,但它能够工作。
A[:, i] = 1/len(A[0])替换pass以消除悬空节点并使矩阵列随机化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接