Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.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 使用+;=关于NumPy数组_Python_Arrays_Numpy - Fatal编程技术网

Python 使用+;=关于NumPy数组

Python 使用+;=关于NumPy数组,python,arrays,numpy,Python,Arrays,Numpy,我使用标准方法在Python中使用NumPy创建对称矩阵/数组: x = rand(500,500) x = (x+x.T) all(x==x.T) > True 现在让我们聪明一点: x = rand(500,500) x += x.T all(x==x.T) > False 等等,什么 x==x.T > array([[ True, True, True, ..., False, False, False], [ True, True, True,

我使用标准方法在Python中使用NumPy创建对称矩阵/数组:

x = rand(500,500)
x = (x+x.T)
all(x==x.T)
> True
现在让我们聪明一点:

x = rand(500,500)
x += x.T
all(x==x.T)
> False
等等,什么

x==x.T
> array([[ True,  True,  True, ..., False, False, False],
       [ True,  True,  True, ..., False, False, False],
       [ True,  True,  True, ..., False, False, False],
       ..., 
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True]], dtype=bool)
左上部分和右下部分是对称的。如果我选择一个更小的数组呢

x = rand(50,50)
x += x.T
all(x==x.T)
> True
好的

x = rand(90,90)
x += x.T
all(x==x.T)
> True

x = rand(91,91)
x += x.T
all(x==x.T)
> False
我只是想确定一下

x = rand(91,91)
x = (x+x.T)
all(x==x.T)
> True
这是一个bug,还是我即将了解有关
+=
和NumPy数组的疯狂知识?

返回数组的视图,这意味着没有分配新数组。这反过来意味着您同时读取和修改数组。很难说为什么某些大小或结果的某些区域会起作用,但很可能与numpy如何处理数组添加(可能它会复制子矩阵)和/或数组视图(可能对于较小的大小,它会创建一个新数组)有关


x=x+x.T
操作之所以有效,是因为您正在创建一个新数组,然后将其分配给
x

问题在于添加操作不是“立即”完成的
x.T
x
的视图,因此当您开始向
x
的每个元素添加时,
x.T
会发生变化。这会弄乱以后的添加

它适用于
(91,91)
以下的大小,这几乎肯定是一个实现细节。使用

x = numpy.random.rand(1000, 1000)
x += x.T.copy()
numpy.all(x==x.T)
#>>> True

修复了这一问题,但实际上没有任何空间优势。

其他人提到的实现细节称为缓冲。您可以在中阅读更多关于它的信息

如果您更详细地查看失败的示例:

>>> a = np.random.rand(91, 91)
>>> a += a.T
>>> a[:5, -1]
array([ 0.83818399,  1.06489316,  1.23675312,  0.00379798,  1.08967428])
>>> a[-1, :5]
array([ 0.83818399,  1.06489316,  1.75091827,  0.00416305,  1.76315071])
因此,第一个错误的值是
90*91+2=8192
,毫不奇怪,这是我们从中得到的:

>>> np.getbufsize()
8192
我们也可以把它调高,然后:

>>> np.setbufsize(16384)  # Must be a multiple of 16
8192  # returns the previous buffer size
>>> a = np.random.rand(91, 91)
>>> a += a.T
>>> np.all(a == a.T)
True
尽管现在:

>>> a = np.random.rand(129, 129)
>>> a += a.T
>>> np.all(a == a.T)
False

这当然是一件危险的事情,因为它确实是一个需要更改的实现细节。

@AndrewJaffe这是Python 3.4.1上的Numpy 1.9,在Anaconda中发布。@jeffalstott yep,我误读了这个问题——我也看到了它的行为。请参阅相关: