Jupyter Snippet CB2nd 05_array_copies

Jupyter Snippet CB2nd 05_array_copies

4.5. Understanding the internals of NumPy to avoid unnecessary array copying

import numpy as np
def aid(x):
    # This function returns the memory
    # block address of an array.
    return x.__array_interface__['data'][0]
a = np.zeros(3)
aid(a), aid(a[1:])
(21535472, 21535480)
def get_data_base(arr):
    """For a given NumPy array, find the base array
    that owns the actual data."""
    base = arr
    while isinstance(base.base, np.ndarray):
        base = base.base
    return base


def arrays_share_data(x, y):
    return get_data_base(x) is get_data_base(y)
print(arrays_share_data(a, a.copy()))
False
print(arrays_share_data(a, a[:1]))
True
import numpy as np
a = np.zeros(10)
ax = aid(a)
ax
32250112
b = a.copy()
aid(b) == ax
False
a *= 2
aid(a) == ax
True
c = a * 2
aid(c) == ax
False
%%timeit a = np.zeros(10000000)
a *= 2
4.85 ms ± 24 µs per loop (mean ± std. dev. of 7 runs,
100 loops each)
%%timeit a = np.zeros(10000000)
b = a * 2
7.7 ms ± 105 µs per loop (mean ± std. dev. of 7 runs,
100 loops each)
a = np.zeros((100, 100))
ax = aid(a)
b = a.reshape((1, -1))
aid(b) == ax
True
c = a.T.reshape((1, -1))
aid(c) == ax
False
%timeit b = a.reshape((1, -1))
330 ns ± 0.517 ns per loop (mean ± std. dev. of 7 runs
    1000000 loops each)
%timeit a.T.reshape((1, -1))
5 µs ± 5.68 ns per loop (mean ± std. dev. of 7 runs,
    100000 loops each)
d = a.flatten()
aid(d) == ax
False
e = a.ravel()
aid(e) == ax
True
%timeit a.flatten()
2.3 µs ± 18.1 ns per loop (mean ± std. dev. of 7 runs,
100000 loops each)
%timeit a.ravel()
199 ns ± 5.02 ns per loop (mean ± std. dev. of 7 runs,
10000000 loops each)
n = 1000
a = np.arange(n)
ac = a[:, np.newaxis]  # column vector
ar = a[np.newaxis, :]  # row vector
%timeit np.tile(ac, (1, n)) * np.tile(ar, (n, 1))
5.7 ms ± 42.6 µs per loop (mean ± std. dev. of 7 runs,
100 loops each)
%timeit ar * ac
784 µs ± 2.39 µs per loop (mean ± std. dev. of 7 runs,
1000 loops each)
offset = array.strides[0] * i1 + array.strides[1] * i2
a = np.random.rand(5000, 5000)
%timeit a[0, :].sum()
2.91 µs ± 20 ns per loop (mean ± std. dev. of 7 runs,
    100000 loops each)
%timeit a[:, 0].sum()
33.7 µs ± 22.7 ns per loop (mean ± std. dev. of 7 runs
    10000 loops each)