Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类属性为&#iadd(+;=)和numpy.random.randn()的奇怪行为_Python_Numpy_Random - Fatal编程技术网

Python 类属性为&#iadd(+;=)和numpy.random.randn()的奇怪行为

Python 类属性为&#iadd(+;=)和numpy.random.randn()的奇怪行为,python,numpy,random,Python,Numpy,Random,我一直在用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__':

我一直在用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个不同的随机数。消除
对象。\uuuu iadd\uuuuu
运算符和/或用常量替换
np.random.randn(.)
,将解决此问题。有人知道它的根是什么吗?

您通过引用返回数组
self.x
,因此您有10个指向同一数组的指针。每次修改数组时,所有十个指针都指向相同的修改版本

如果每次都要返回数组的单独副本,可以在
add\u random
函数中
return self.x.copy()


另一种修复方法是将
np.random.rand(1)
替换为
np.random.rand()
so
self.x
将保持标量而不是向上转换为数组。

您通过引用返回数组
self.x
,因此您有10个指向同一数组的指针。每次修改数组时,所有十个指针都指向相同的修改版本

如果每次都要返回数组的单独副本,可以在
add\u random
函数中
return self.x.copy()

另一种修复方法是将
np.random.rand(1)
替换为
np.random.rand()
,这样
self.x
将保持标量而不是向上转换为数组。

np.random.randn(1)
返回包含单个元素的数组:

In [27]: np.random.randn(1)
Out[27]: array([-1.90409169])
第一次执行此行时

self.x += np.random.randn(1)
self.x
——最初是Python整数——被numpy数组替换。该行的后续执行会就地修改
x
,因为numpy数组就是这样实现就地加法的。因此
return self.x
总是返回相同的数组。因此,您在主部分中创建的列表是一个包含重复10次的相同对象的列表

解决此问题的一种方法是使用
np.random.randn()
而不是
np.random.randn(1)
np.random.randn()
返回一个标量,因此赋值
self.x+=np.random.randn(1)
每次执行时都会创建一个新的
self.x
对象。

np.random.randn(1)
返回一个包含单个元素的数组:

In [27]: np.random.randn(1)
Out[27]: array([-1.90409169])
第一次执行此行时

self.x += np.random.randn(1)
self.x
——最初是Python整数——被numpy数组替换。该行的后续执行会就地修改
x
,因为numpy数组就是这样实现就地加法的。因此
return self.x
总是返回相同的数组。因此,您在主部分中创建的列表是一个包含重复10次的相同对象的列表


解决此问题的一种方法是使用
np.random.randn()
而不是
np.random.randn(1)
np.random.randn()
返回一个标量,因此赋值
self.x+=np.random.randn(1)
每次执行时都会创建一个新的
self.x
对象。

WarrenWeckesser解释了问题的根源,但从根本上说,使用
numpy
来实现这一点效率非常低。每次都要创建数组对象,这会带来很大的开销。相反,请使用
random.gauss
注意,如果您想使用
numpy
有效地执行此操作,那么只需使用
np.random.randn(10).cumsum()
WarrenWeckesser解释了问题的根源,但从根本上说,使用
numpy
执行此操作效率极低。每次都要创建数组对象,这会带来很大的开销。相反,请使用
random.gauss
注意,如果您想使用
numpy
有效地执行此操作,那么只需使用
np.random.randn(10.cumsum()
谢谢–我将“整数”改为“标量”以使其更清晰。谢谢–我将“整数”改为“标量”以使其更清晰。