[英]Mean of normal distribution generated using numpy.random.randn() is not '0'
[英]Weird behavior with class attribute, __iadd__ (+=) and numpy.random.randn()
我一直在用Python和Numpy建模一个随机过程,并通过以下代码见证怪异的行为:
import numpy as np
class Example( object ):
def __init__( self ):
self.x = 0
def add_random( self ):
self.x += np.random.randn(1)
return self.x
if __name__ == '__main__':
example = Example()
state = []
for x in range(10):
state.append( example.add_random() )
print state
这将返回由10个相同的随机数组成的数组,而不是预期的10个不同的随机数。 消除object.__iadd__
运算符和/或用np.random.randn(.)
替换np.random.randn(.)
将解决此问题。 有人知道这是什么根源吗?
np.random.randn(1)
返回一个包含单个元素的数组:
In [27]: np.random.randn(1)
Out[27]: array([-1.90409169])
第一次执行此行
self.x += np.random.randn(1)
self.x
--initially一个Python整数-由numpy的阵列代替。 随后执行该行会修改x
in-place ,因为这是numpy数组实现就地加法的方式。 因此, return self.x
总是返回相同的数组。 因此,您在主要部分中创建的列表是一个包含重复10次相同对象的列表。
解决此问题的一种方法是使用np.random.randn()
而不是np.random.randn(1)
。 np.random.randn()
返回一个标量,因此每次执行self.x += np.random.randn(1)
都会创建一个新的self.x
对象。
您将通过引用返回数组self.x
,因此您有10个指向同一数组的指针。 每次修改数组时,所有十个指针都指向相同的修改版本。
如果要每次返回数组的单独副本,则可以在add_random
函数中return self.x.copy()
。
另一种解决方法是将np.random.rand(1)
替换为np.random.rand()
以便self.x
将保持标量而不是向上转换为数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.