In [64]: x = np.zeros((3, 3))
In [65]: x
Out[65]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
Some useful information about 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' is some sort of pointer to the c array that stores the 9 values of x. It is accessed as 2d using the strides - step by 8 bytes to go from one column to the next, by 3*28 to go to the next row
y is view, an new array, but which shares memory with 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.]])
Modifying a y element modifies the same one in 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.]])
A view of a row:
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
Modifying a z element changes y also (if the overlap):
In [79]: z[0]=3
In [80]: y
Out[80]: array([3., 2., 0.])
This striding also makes reshaping fast - no data copies. Also transpose is fast.
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