Python 使用+;=关于NumPy数组
我使用标准方法在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,
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,我误读了这个问题——我也看到了它的行为。请参阅相关: