import numpy as np
x = np.zeros((3, 3))
y = x[:, 0]
y[1] = 2 # x[1,0] is changed
print(x)
z = x[0, :]
z[2] = 3 # x[0, 2] is changed
print(x)
数据是如何存储和实现的?
如果使用c(或fortran(,则二维数组x[3][3]
z=x[0],:],返回指向x[0][0]地址的指针,然后z[2]=3可以更改x[0][2]的值。
但是y[1]=2是怎么做的呢?x[0][0]x[1][0]x[2][0]的地址不连续。
numpy是否使用另一个变量来记住下一个元素?
In [64]: x = np.zeros((3, 3))
In [65]: x
Out[65]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
关于x
:的一些有用信息
In [66]: x.__array_interface__
Out[66]:
{'data': (1510169114000, False),
'strides': None,
'descr': [('', '<f8')],
'typestr': '<f8',
'shape': (3, 3),
'version': 3}
In [67]: x.strides
Out[67]: (24, 8)
"data"是指向存储x
的9个值的c数组的某种指针。使用步幅以2d的形式访问它——从一列到下一列按8字节的步幅,到下一行按3*28的步幅
y
是view
,一个新的阵列,但与x
:共享内存
In [68]: y = x[:, 0]
In [69]: y
Out[69]: array([0., 0., 0.])
In [70]: y.__array_interface__
Out[70]:
{'data': (1510169114000, False), # same data as x
'strides': (24,), # going down rows
'descr': [('', '<f8')],
'typestr': '<f8',
'shape': (3,),
'version': 3}
In [71]: y.base
Out[71]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
修改y
元素会修改x
:中的相同元素
In [72]: y[1] = 2
In [73]: y
Out[73]: array([0., 2., 0.])
In [74]: x
Out[74]:
array([[0., 0., 0.],
[2., 0., 0.],
[0., 0., 0.]])
一排视图:
In [75]: z = x[0, :]
In [76]: z
Out[76]: array([0., 0., 0.])
In [77]: z.__array_interface__
Out[77]:
{'data': (1510169114000, False),
'strides': None,
'descr': [('', '<f8')],
'typestr': '<f8',
'shape': (3,),
'version': 3}
In [78]: z.strides
Out[78]: (8,) # same column stride
修改z
元素也会更改y
(如果重叠(:
In [79]: z[0]=3
In [80]: y
Out[80]: array([3., 2., 0.])
这种跨越也使重塑变得快速——没有数据拷贝。转置也很快。
In [81]: xt = x.transpose()
In [82]: xt
Out[82]:
array([[3., 2., 0.],
[0., 0., 0.],
[0., 0., 0.]])
In [83]: xt.strides
Out[83]: (8, 24) # same base, just switched strides