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

Python 创建任意大小的矩阵,其中行总和为1?,python,matrix,random,markov,Python,Matrix,Random,Markov,我的任务是为任意数量的事件创建一个模拟离散时间马尔可夫链的程序。然而,现在我正在努力创建正确的随机矩阵来表示概率。右随机矩阵是一个矩阵,它的行项总和为1。对于给定的大小,我知道如何编写矩阵,但是问题是,对于任意大小,我不知道如何编写矩阵 例如:这是我的3x3矩阵代码,以及我得到的输出示例 然而,我的代码并不是每次都有效——有时行中的第三个条目是负数,因为前两个太大了。我不知道如何解决这个问题,据我所知,Python中没有一个函数可以让你生成随机数,这些随机数和特定的东西相加 感谢您的帮助 (请

我的任务是为任意数量的事件创建一个模拟离散时间马尔可夫链的程序。然而,现在我正在努力创建正确的随机矩阵来表示概率。右随机矩阵是一个矩阵,它的行项总和为1。对于给定的大小,我知道如何编写矩阵,但是问题是,对于任意大小,我不知道如何编写矩阵

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

然而,我的代码并不是每次都有效——有时行中的第三个条目是负数,因为前两个太大了。我不知道如何解决这个问题,据我所知,Python中没有一个函数可以让你生成随机数,这些随机数和特定的东西相加

感谢您的帮助


(请注意,这不是一个家庭作业问题,只是为了在我的数学课上获得额外学分,教授并不介意使用外部资源。)

使用随机值生成NxN矩阵。
每行:
求S行的和

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

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

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

若只需要非负值,则生成非负值随机数,并将行中的每个值除以此行的总和

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

以下是一些代码:

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'中使用了precision,如果这是1000,则表示随机数在逗号后有3位数字。在y示例中,使用了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]]
右随机矩阵是一个实平方矩阵,每行总和为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]])
解释 我们创建一个nxm矩阵

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

然后,我们使用
np将其应用于矩阵的每一行。使用
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\u-alow\u axis()
,以便在轴上的每个元素上调用该函数,在本例中,它是行

还有其他的方式也很相似

制作一个函数并像上面的任何方法一样应用它比在每一行中循环每个项目要好,更快、更少的代码,更容易阅读/理解意图,使用@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.0的非负元素的M x N矩阵。上述MBo评论指出:

如果只需要非负值,则生成非负值随机数, 将行中的每个值除以该行的和

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

只有当存储的矩阵完全由整数(不一定是整数)组成时,才会出现这种情况。否则,生成的矩阵可能包含负数,矩阵越大,负元素越多

这可以通过以下方式实现:

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

我该怎么做呢?到目前为止,我所拥有的只是生成一个随机nxn矩阵的代码,然后是计算每行总和的代码,但是我如何从行中的每个条目中减去该值呢?非常感谢。这太完美了。我还有一个小问题要问。现在我有了我需要的矩阵,找出λ=1的特征值对应的特征向量的最佳方法是什么?到目前为止,我知道的唯一一种方法是通过使用scipy.sparse.linalg.eigs(),来找到特定特征值的特征向量,但是当我的矩阵不是稀疏矩阵时,这种方法准确吗?很遗憾,我无法帮到你。我不知道。谢谢你的帮助。我继续实施了Mihai的解决方案,但我也对此表示感谢。感谢您的解决方案和逐步解释。此解决方案不正确,因为即使在您的示例中,结果也可能有负面条目@Sait答案具有更好的规范性