import numpy as np
a = np.arange(15).reshape(3, 5)
a
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
a[1, 1]
6
a[0]
array([0, 1, 2, 3, 4])
a[:, 0]
array([ 0, 5, 10])
a[0:2, 0:2]
array([[0, 1], [5, 6]])
What does this do?|
a[10:1000]
array([], shape=(0, 5), dtype=int64)
a * 100
array([[ 0, 100, 200, 300, 400], [ 500, 600, 700, 800, 900], [1000, 1100, 1200, 1300, 1400]])
a - a[0]
array([[ 0, 0, 0, 0, 0], [ 5, 5, 5, 5, 5], [10, 10, 10, 10, 10]])
a - a[:, 0] # nope!
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[55], line 1 ----> 1 a - a[:, 0] # nope! ValueError: operands could not be broadcast together with shapes (3,5) (3,)
Quoting https://jakevdp.github.io/PythonDataScienceHandbook/02.05-computation-on-arrays-broadcasting.html
Rule 1: If the two arrays differ in their number of dimensions, the shape of the one with fewer dimensions is padded with ones on its leading (left) side.
Rule 2: If the shape of the two arrays does not match in any dimension, the array with shape equal to 1 in that dimension is stretched to match the other shape.
Rule 3: If in any dimension the sizes disagree and neither is equal to 1, an error is raised.
print(a.shape)
print(a[:, 0].shape)
(3, 5) (3,)
a[:, 0]
array([ 0, 5, 10])
a[:, 0, np.newaxis]
array([[ 0], [ 5], [10]])
print(a.shape)
print(a[:, 0, np.newaxis].shape)
(3, 5) (3, 1)
a - a[:, 0, np.newaxis]
array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])
Slices can be created on their own and reused.
every2 = np.s_[::2]
every10 = np.s_[::10]
b = np.arange(15)
print(f"{b = }")
print(f"{every2 = }")
print(f"{every10 = }")
print(f"{b[every2] = }")
print(f"{b[every10] = }")
b = array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) every2 = slice(None, None, 2) every10 = slice(None, None, 10) b[every2] = array([ 0, 2, 4, 6, 8, 10, 12, 14]) b[every10] = array([ 0, 10])
Great reference on slices in Python in general and multi-dimensional slicing in particular: https://quansight-labs.github.io/ndindex/slices.html
a.shape
(3, 5)
a.ndim
2
a.size
15
a.ndim
2
a.nbytes
120
a.dtype
dtype('int64')
a.tolist()
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]
A block of memory with rules to "striding" through it and interpreting it
a.data
<memory at 0x7f76ff7a9cb0>
a.dtype.itemsize
8
a.shape
(3, 5)
a.strides
(40, 8)
print(a[0])
print(a[:, 0])
[0 1 2 3 4] [ 0 5 10]
a.data
<memory at 0x7f76ff7a9e50>
a.data.hex()
'00000000000000000100000000000000020000000000000003000000000000000400000000000000050000000000000006000000000000000700000000000000080000000000000009000000000000000a000000000000000b000000000000000c000000000000000d000000000000000e00000000000000'