numpy基础练习100题(41-70)
github项目地址:https://github.com/rougier/numpy-100
(41) How to sum a small array faster than np.sum?
Z = np.arange(10)
np.add.reduce(Z)
# 45
(42) Consider two random array A and B, check if they are equal
A = np.random.randint(0,2,5)
B = np.random.randint(0,2,5)
# Assuming identical shape of the arrays and a tolerance for the comparison of values
equal = np.allclose(A, B)
print(equal)
# False
# Checking both the shape and the element values, no tolerance (values have to be exactly equal)
equal = np.array_equal(A, B)
print(equal)
# False
(43) Make an array immutable (read-only)
Z = np.zeros(10)
Z.flags.writeable = False
Z[0] = 1
# ValueError: assignment destination is read-only
(44) Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates
Z = np.random.random((10, 2))
X, Y = Z[:, 0], Z[:, 1]
R = np.sqrt(X ** 2 + Y ** 2)
T = np.arctan2(Y, X)
print(R)
print(T)
(45) Create random vector of size 10 and replace the maximum value by 0
Z = np.random.random(10)
Z[Z.argmax()] = 0
print(Z)
(46) Create a structured array with x and y coordinates covering the [0,1]x[0,1] area
Z = np.zeros((5, 5), [('x', float), ('y', float)])
#Z = np.zeros((5, 5), dtype=[('x', float), ('y', float)])
Z['x'], Z['y'] = np.meshgrid(np.linspace(0, 1, 5),
np.linspace(0, 1, 5))
print(Z)
# [[( 0. , 0. ) ( 0.25, 0. ) ( 0.5 , 0. ) ( 0.75, 0. )
# ( 1. , 0. )]
# [( 0. , 0.25) ( 0.25, 0.25) ( 0.5 , 0.25) ( 0.75, 0.25)
# ( 1. , 0.25)]
# [( 0. , 0.5 ) ( 0.25, 0.5 ) ( 0.5 , 0.5 ) ( 0.75, 0.5 )
# ( 1. , 0.5 )]
# [( 0. , 0.75) ( 0.25, 0.75) ( 0.5 , 0.75) ( 0.75, 0.75)
# ( 1. , 0.75)]
# [( 0. , 1. ) ( 0.25, 1. ) ( 0.5 , 1. ) ( 0.75, 1. )
# ( 1. , 1. )]]
# another solution
xx, yy = np.meshgrid(np.linspace(0, 1, 5),
np.linspace(0, 1, 5))
Z = np.c_[xx.ravel(), yy.ravel()]
print(Z)
(47) Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj))
X = np.arange(8)
Y = X + 0.5
C = 1.0 / np.subtract.outer(X, Y)
print(np.linalg.det(C))
# 3638.16363712
# simple version
X = [4, 5, 6]
Y = [1, 2, 3]
C = 1.0 / np.subtract.outer(X, Y)
print(C)
# [[ 0.33333333 0.5 1. ]
# [ 0.25 0.33333333 0.5 ]
# [ 0.2 0.25 0.33333333]]
(48) Print the minimum and maximum representable value for each numpy scalar type
for dtype in [np.int8, np.int32, np.int64]:
print(np.iinfo(dtype).min)
print(np.iinfo(dtype).max)
for dtype in [np.float32, np.float64]:
print(np.finfo(dtype).min)
print(np.finfo(dtype).max)
print(np.finfo(dtype).eps)
# -128
# 127
# -2147483648
# 2147483647
# -9223372036854775808
# 9223372036854775807
# -3.40282e+38
# 3.40282e+38
# 1.19209e-07
# -1.79769313486e+308
# 1.79769313486e+308
# 2.22044604925e-16
(49) How to print all the values of an array?
np.set_printoptions(threshold=np.nan)
# need larger array to show the difference
Z = np.zeros((16, 16))
print(Z)
(50) How to find the closest value (to a given scalar) in a vector?
Z = np.arange(100)
v = np.random.uniform(0,100)
index = (np.abs(Z - v)).argmin()
print(Z[index])
(51) Create a structured array representing a position (x,y) and a color (r,g,b)
Z = np.zeros(10, [('position', [('x', float, 1),
('y', float, 1)]),
('color', [('r', float, 1),
('g', float, 1),
('b', float, 1)])])
print(Z)
# [(( 0., 0.), ( 0., 0., 0.)) (( 0., 0.), ( 0., 0., 0.))
# (( 0., 0.), ( 0., 0., 0.)) (( 0., 0.), ( 0., 0., 0.))
# (( 0., 0.), ( 0., 0., 0.)) (( 0., 0.), ( 0., 0., 0.))
# (( 0., 0.), ( 0., 0., 0.)) (( 0., 0.), ( 0., 0., 0.))
# (( 0., 0.), ( 0., 0., 0.)) (( 0., 0.), ( 0., 0., 0.))]
(52) Consider a random vector with shape (100,2) representing coordinates, find point by point distances
Z = np.random.random((10, 2))
X, Y = np.atleast_2d(Z[:, 0], Z[:, 1])
D = np.sqrt((X - X.T) ** 2 + (Y - Y.T) ** 2)
print(D)
# Much faster with scipy
import scipy.spatial
Z = np.random.random((10,2))
D = scipy.spatial.distance.cdist(Z,Z)
print(D)
(53) How to convert a float (32 bits) array into an integer (32 bits) in place?
Z = np.array([1.2, 2.3, 3.4], dtype=np.float32)
Z = Z.astype(np.int32, copy=False)
print(Z)
# [1 2 3]
# original solution
Z = np.arange(10, dtype=np.int32)
Z = Z.astype(np.float32, copy=False)
print(Z)
# [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
(54) How to read the following file?
from io import StringIO
# Fake file
s = StringIO(unicode("1, 2, 3, 4, 5\n" +
"6, , , 7, 8\n" +
" , , 9,10,11\n"))
Z = np.genfromtxt(s, delimiter=",", dtype=np.int)
print(Z)
# [[ 1 2 3 4 5]
# [ 6 -1 -1 7 8]
# [-1 -1 9 10 11]]
(55) What is the equivalent of enumerate for numpy arrays?
Z = np.arange(4).reshape(2,2)
for index, value in np.ndenumerate(Z):
print(index, value)
for index in np.ndindex(Z.shape):
print(index, Z[index])
# ((0L, 0L), 0)
# ((0L, 1L), 1)
# ((1L, 0L), 2)
# ((1L, 1L), 3)
# ((0, 0), 0)
# ((0, 1), 1)
# ((1, 0), 2)
# ((1, 1), 3)
(56) Generate a generic 2D Gaussian-like array
X, Y = np.meshgrid(np.linspace(-1, 1, 4), np.linspace(-1, 1, 4))
D = np.sqrt(X * X + Y * Y)
sigma, mu = 1.0, 0.0
G = np.exp(-((D - mu) ** 2 / (2.0 * sigma ** 2)))
print(G)
(57) How to randomly place p elements in a 2D array?
n = 4
p = 3
Z = np.zeros((n,n))
np.put(Z, np.random.choice(range(n * n), p, replace=False), 1)
print(Z)
# [[ 0. 0. 1. 0.]
# [ 1. 0. 0. 0.]
# [ 0. 1. 0. 0.]
# [ 0. 0. 0. 0.]]
(58) Subtract the mean of each row of a matrix
X = np.random.rand(3, 3)
Y = X - X.mean(axis=1).reshape(-1, 1)
print(Y)
# latest solution
Y = X - X.mean(axis=1, keepdims=True)
print(Y)
(59) How to sort an array by the nth column?
Z = np.random.randint(0, 10, (3, 3))
print(Z)
print(Z[Z[:,1].argsort()])
(60) How to tell if a given 2D array has null columns?
Z = np.random.randint(0, 3, (3, 10))
print((~Z.any(axis = 0)).any())
(61) Find the nearest value from a given value in an array
Z = np.random.uniform(0, 1, 10)
z = 0.5
# flat is used for 2d array
# Z = np.random.random((10, 10))
m = Z.flat[np.abs(Z - z).argmin()]
print(m)
(62) Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator?
A = np.arange(3).reshape(3, 1)
B = np.arange(3).reshape(1, 3)
it = np.nditer([A, B, None])
for x, y, z in it: z[...] = x + y
print(it.operands[2])
# [[0 1 2]
# [1 2 3]
# [2 3 4]]
(63) Create an array class that has a name attribute
class NamedArray(np.ndarray):
def __new__(cls, array, name="no name"):
obj = np.asarray(array).view(cls)
obj.name = name
return obj
def __array_finalize__(self, obj):
if obj is None: return
self.info = getattr(obj, 'name', "no name")
Z = NamedArray(np.arange(10), "range_10")
print(Z.name)
# range_10
(64) Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)?
Z = np.ones(10)
I = np.random.randint(0, len(Z), 20)
Z += np.bincount(I, minlength=len(Z))
print(Z)
# another solution
np.add.at(Z, I, 1)
print(Z)
(65) How to accumulate elements of a vector (X) to an array (F) based on an index list (I)?
X = [1, 2, 3, 4, 5, 6]
I = [1, 3, 9, 3, 4, 1]
F = np.bincount(I, X)
print(F)
# [ 0. 7. 0. 6. 5. 0. 0. 0. 0. 3.]
(66) Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors
w, h = 16, 16
I = np.random.randint(0, 2, (h, w, 3)).astype(np.ubyte)
# Note that we should compute 256*256 first.
# Otherwise numpy will only promote F.dtype to 'uint16' and overfolw will occur
F = I[..., 0] * (256 * 256) + I[..., 1] * 256 + I[..., 2]
n = len(np.unique(F))
print(n)
(67) Considering a four dimensions array, how to get sum over the last two axis at once?
A = np.random.randint(0, 10, (3, 4, 3, 4))
# solution by passing a tuple of axes (introduced in numpy 1.7.0)
ans = A.sum(axis=(-2, -1))
print(ans)
# solution by flattening the last two dimensions into one
# (useful for functions that don't accept tuples for axis argument)
ans = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1)
print(ans)
(68) Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices?
D = np.random.uniform(0, 1, 100)
S = np.random.randint(0, 10, 100)
D_sums = np.bincount(S, weights=D)
D_counts = np.bincount(S)
D_means = D_sums / D_counts
print(D_means)
# Pandas solution as a reference due to more intuitive code
import pandas as pd
print(pd.Series(D).groupby(S).mean())
(69) How to get the diagonal of a dot product?
A = np.random.uniform(0, 1, (5, 5))
B = np.random.uniform(0, 1, (5, 5))
# Slow version
np.diag(np.dot(A, B))
# Fast version
np.sum(A * B.T, axis=1)
# Faster version
np.einsum("ij,ji->i", A, B)
(70) Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value?
Z = np.array([1, 2, 3, 4, 5])
nz = 3
Z0 = np.zeros(len(Z) + (len(Z) - 1) * nz)
Z0[::nz + 1] = Z
print(Z0)