可以用NumPy重现MATLAB的randn()吗?

10 投票
3 回答
10349 浏览
提问于 2025-04-16 04:12

我在想,能不能用NumPy完全复制MATLAB中的randn()函数生成的随机数序列。我用Python和NumPy写了自己的代码,但得到的结果和别人用MATLAB写的代码有点不一样,我很难找到原因,因为随机数的生成方式不同。

我找到了一些numpy.random.seed的值,这样可以让第一次生成的随机数相同,但从第二次开始,结果就完全不同了。我需要生成大约20,000次的多元正态分布随机数,所以我不想只是把MATLAB生成的随机数保存下来,然后在Python中读取。

3 个回答

4

我想进一步说明一下使用twister/seeding方法的事情:MATLAB和numpy使用相同的种子生成相同的随机数序列,但它们填充矩阵的方式不同。

MATLAB是从开始填充矩阵,而python则是从开始填充。所以为了让两个程序生成的矩阵看起来一样,你需要进行转置:

MATLAB:

rand('twister', 1337);
A = rand(3,5)
A = 
 Columns 1 through 2
   0.262024675015582   0.459316887214567
   0.158683972154466   0.321000540520167
   0.278126519494360   0.518392820597537
  Columns 3 through 4
   0.261942925565145   0.115274226683149
   0.976085284877434   0.386275068634359
   0.732814552690482   0.628501179539712
  Column 5
   0.125057926335599
   0.983548605143641
   0.443224868645128

python:

import numpy as np
np.random.seed(1337)
A = np.random.random((5,3))
A.T
array([[ 0.26202468,  0.45931689,  0.26194293,  0.11527423,  0.12505793],
       [ 0.15868397,  0.32100054,  0.97608528,  0.38627507,  0.98354861],
       [ 0.27812652,  0.51839282,  0.73281455,  0.62850118,  0.44322487]])

注意:我也把这个答案放在了一个类似的问题上:比较使用随机数生成的Matlab和Numpy代码

5

如果你把随机数生成器设置为相同的种子,理论上它会生成相同的数字,比如在matlab中。我不太确定怎么做最好,但这个方法似乎有效,在matlab中可以这样操作:

rand('twister', 5489)

在numy中对应的操作是:

np.random.seed(5489)

这样可以(重新)初始化你的随机数生成器。对我来说,这样做可以让rand()和np.random.random()生成相同的数字,不过randn就不行了,我不太确定有没有简单的方法可以做到这一点。

在较新的matlab版本中,你可能可以设置一个RandStream,使其属性与numpy相同;而在旧版本中,你可以在matlab中复现numpy的randn(或者反过来)。numpy使用极坐标形式来从np.random.random()生成均匀分布的数字(这里给出的第二个算法:http://www.taygeta.com/random/gaussian.html)。你可以在matlab中直接写这个算法,以便从matlab的rand函数生成与numpy相同的randn数字。

如果你不需要大量的随机数,可以直接把它们保存到一个.mat文件中,然后通过scipy.io读取...

8

用户问是否可以在Python中复现Matlab的randn()输出,而不是rand。我还没找到设置算法或种子的办法来精确复现randn()的结果,但下面的解决方案对我来说是有效的。

在Matlab中:生成正态分布的随机数可以这样做:

rng(1);
norminv(rand(1,5),0,1)
ans = 
   -0.2095    0.5838   -3.6849   -0.5177   -1.0504

在Python中:生成正态分布的随机数可以这样做:

import numpy as np
from scipy.stats import norm
np.random.seed(1)
norm.ppf(np.random.rand(1,5))
array([[-0.2095,  0.5838, -3.6849, -0.5177,-1.0504]])

在从Matlab转到Python或反过来的时候,能够有一些函数来复现相同的随机数是非常方便的。

撰写回答