numpy是如何实现切片的


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的步幅

yview,一个新的阵列,但与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

最新更新