创建一个任意大小的矩阵,其中行总和为1?

时间:2015-07-12 05:39:31

标签: python matrix random markov

我的任务是为任意数量的事件创建一个模拟离散时间马尔可夫链的程序。然而,现在我正在努力的部分是创建代表概率的正确的随机矩阵。右边的随机矩阵是一个矩阵,其行条目总和为1.对于给定的大小,我知道如何编写执行该操作的矩阵,但问题是我不知道如何做到这一点任意大小。

例如:这是我的3x3矩阵代码,以及我得到的输出示例。

http://pastebin.com/4GXpAYTM

但是,我的代码每次都不起作用 - 有时候行中的第三个条目是否定的,因为前两个条目太大了。而且我不知道如何解决这个问题,据我所知,Python中没有一个函数能够生成随机数,特别是对某些东西进行求和。

感谢任何帮助。

(请注意,这不是一个家庭作业问题,它仅用于我的数学课程中的额外学分,教授不介意使用外部资源。)

5 个答案:

答案 0 :(得分:8)

使用@ MBo的想法:

In [16]: matrix = np.random.rand(3,3)

In [17]: matrix/matrix.sum(axis=1)[:,None]
Out[17]:
array([[ 0.25429337,  0.22502947,  0.52067716],
       [ 0.17744651,  0.42358254,  0.39897096],
       [ 0.36179247,  0.28707039,  0.35113714]])

In [18]:

答案 1 :(得分:3)

生成具有随机值的NxN矩阵 对于每一行:
找到行S的总和

S[j] = Sum(0..N-1){A[j, i]}

然后从该行中的每个值中减去(S-1)/ N

A[j, i] = A[j, i] - (S[j] - 1) / N

如果只需要非负值,则生成非负的random,并将行中的每个值除以该行的总和

A[j, i] = A[j, i] / S[j]

答案 2 :(得分:3)

以下是一些代码:

import random

precision = 1000000

def f(n) :
    matrix = []
    for l in range(n) :
        lineLst = []
        sum = 0
        crtPrec = precision
        for i in range(n-1) :
            val = random.randrange(crtPrec)
            sum += val
            lineLst.append(float(val)/precision)
            crtPrec -= val
        lineLst.append(float(precision - sum)/precision)
        matrix.append(lineLst)
    return matrix


matrix = f(5)
print matrix

我假设随机数必须为正数,原始数字的总和必须为1.我在变量'precision'中使用精度给出,如果这是1000则意味着随机数将有3位数在逗号之后。在示例中,使用了6位数字,您可以使用更多数字。

输出:

[[0.086015, 0.596464, 0.161664, 0.03386, 0.121997], 
[0.540478, 0.040961, 0.374275, 0.003793, 0.040493], 
[0.046263, 0.249761, 0.460089, 0.006739, 0.237148], 
[0.594743, 0.125554, 0.142809, 0.056124, 0.08077], 
[0.746161, 0.151382, 0.068062, 0.005772, 0.028623]]

答案 3 :(得分:1)

  

右随机矩阵是一个实矩阵,每行总和为1。

以下是您可以创建函数的示例,我将其留给您作为家庭作业

In [26]: import numpy as np

In [27]: N, M = 5, 5

In [28]: matrix = np.random.rand(N, M)

In [29]: matrix
Out[29]:
array([[ 0.27926909,  0.37026136,  0.35978443,  0.75216853,  0.53517512],
       [ 0.93285517,  0.54825643,  0.43948394,  0.15134782,  0.31310007],
       [ 0.91934362,  0.51707873,  0.3604323 ,  0.78487053,  0.85757986],
       [ 0.53595238,  0.80467646,  0.88001499,  0.4668259 ,  0.63567632],
       [ 0.83359167,  0.41603073,  0.21192656,  0.22650423,  0.95721952]])

In [30]: matrix = np.apply_along_axis(lambda x: x - (np.sum(x) - 1)/len(x), 1, matrix)

In [31]: matrix
Out[31]:
array([[ 0.01993739,  0.11092965,  0.10045272,  0.49283682,  0.27584341],
       [ 0.65584649,  0.27124774,  0.16247526, -0.12566087,  0.03609139],
       [ 0.43148261,  0.02921772, -0.12742871,  0.29700952,  0.36971886],
       [ 0.07132317,  0.34004725,  0.41538578,  0.00219669,  0.17104711],
       [ 0.50453713,  0.08697618, -0.11712798, -0.10255031,  0.62816498]])

说明

我们创建一个N x M矩阵

然后我们计算要从每个项目中逐行减去的(sum - 1) / N

然后我们将np.apply_along_axis()axis=1一起应用于每一行,将其应用于矩阵的每一行

验证结果

每行需要总计1个

In [37]: matrix.sum(axis=1)
Out[37]: array([ 1.,  1.,  1.,  1.,  1.])
  

但是如何从行中的每个条目中减去该值?

在我的例子中,我使用的lambda等同于此函数

def subtract_value(x):
    return x - (np.sum(x) - 1)/len(x)

您可以将函数传递给apply_along_axis()以在轴上的每个元素上调用,在我们的示例中,它是行

还有其他方式,如numpy.vectorize()numpy.frompyfunc

制作一个函数并像上面的任何方法一样应用它比循环遍历每一行中的每个项目更快,代码更少,更容易阅读/理解意图

答案 4 :(得分:1)

错过了一个小问题。随机矩阵是行总数为1.0的非负元素的M x N矩阵。上面的MBo评论指出:

  

如果仅需要非负值,请生成非负随机数,   并将行中的每个值除以该行的总和

     

A [j,i] = A [j,i] / S [j]

仅当存储的矩阵完全由整数(不一定是整数)组成时,这才是正确的。否则,结果矩阵可能包含负数,矩阵越大,负数就越多。

这可以使用:

 X[i, j] = Math.Abs(random.Next(100, 900));