numpy基础练习100题(71-100)

numpy基础练习100题(71-100)
github项目地址:https://github.com/rougier/numpy-100

(71) Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)?
A = np.ones((5, 5, 3))
B = 2 * np.ones((5, 5))
print(A * B[:, :, None])

# simple version
A = np.ones((2, 3, 4))
B = np.arange(6).reshape((2, 3))
print(A * B[:, :, None])
# [[[ 0.  0.  0.  0.]
#   [ 1.  1.  1.  1.]
#   [ 2.  2.  2.  2.]]
#
#  [[ 3.  3.  3.  3.]
#   [ 4.  4.  4.  4.]
#   [ 5.  5.  5.  5.]]]
print(A * B[:, :, np.newaxis])
# [[[ 0.  0.  0.  0.]
#   [ 1.  1.  1.  1.]
#   [ 2.  2.  2.  2.]]
#
#  [[ 3.  3.  3.  3.]
#   [ 4.  4.  4.  4.]
#   [ 5.  5.  5.  5.]]]
(72) How to swap two rows of an array?
A = np.arange(25).reshape(5,5)
A[[0, 1]] = A[[1, 0]]
print(A)
# [[ 5  6  7  8  9]
#  [ 0  1  2  3  4]
#  [10 11 12 13 14]
#  [15 16 17 18 19]
#  [20 21 22 23 24]]
(73) Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles
faces = np.random.randint(0, 100, (10, 3))
F = np.roll(faces.repeat(2, axis=1), -1, axis=1)
F = F.reshape(len(F) * 3, 2)
F = np.sort(F, axis=1)
G = F.view(dtype=[('p0', F.dtype),('p1', F.dtype)])
G = np.unique(G)
print(G)
(74) Given an array C that is a bincount, how to produce an array A such that np.bincount(A) == C?
C = np.bincount([1, 1, 2, 3, 4, 4, 6])
A = np.repeat(np.arange(len(C)), C)
print(A)
# [1 1 2 3 4 4 6]
(75) How to compute averages using a sliding window over an array?
def moving_average(a, n=3):
    ret = np.cumsum(a, dtype=float)
    ret[n:] = ret[n:] - ret[:-n]
    return ret[n - 1:] / n
Z = np.arange(20)
print(moving_average(Z, n=3))
# [  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.  15.
#   16.  17.  18.]
(76) Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1])
from numpy.lib import stride_tricks
def rolling(a, window):
    shape = (a.size - window + 1, window)
    strides = (a.itemsize, a.itemsize)
    return stride_tricks.as_strided(a, shape=shape, strides=strides)
Z = rolling(np.arange(10), 3)
print(Z)
# [[0 1 2]
#  [1 2 3]
#  [2 3 4]
#  [3 4 5]
#  [4 5 6]
#  [5 6 7]
#  [6 7 8]
#  [7 8 9]]
(77) How to negate a boolean, or to change the sign of a float inplace?
Z = np.random.randint(0, 2, 10)
print(np.logical_not(Z, out=Z))
Z = np.random.uniform(-1.0, 1.0, 10)
print(np.negative(Z, out=Z))
(78) Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])?
def distance(P0, P1, p):
    T = P1 - P0
    L = (T ** 2).sum(axis=1)
    U = -((P0[:, 0] - p[:, 0]) * T[:, 0] + (P0[:, 1] - p[:, 1]) * T[:, 1]) / L
    U = U.reshape(len(U), 1)
    D = P0 + U * T - p
    return np.sqrt((D ** 2).sum(axis=1))

P0 = np.random.uniform(-10, 10, (10, 2))
P1 = np.random.uniform(-10, 10, (10, 2))
p  = np.random.uniform(-10, 10, (1, 2))
print(distance(P0, P1, p))
(79) Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])?
# based on distance function from previous question
P0 = np.random.uniform(-10, 10, (10, 2))
P1 = np.random.uniform(-10, 10, (10, 2))
p = np.random.uniform(-10, 10, (10, 2))
print(np.array([distance(P0, P1, p_i) for p_i in p]))
(80) Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a fill value when necessary)
Z = np.random.randint(0, 10, (10, 10))
shape = (5, 5)
fill  = 0
position = (1, 1)

R = np.ones(shape, dtype=Z.dtype) * fill
P  = np.array(list(position)).astype(int)
Rs = np.array(list(R.shape)).astype(int)
Zs = np.array(list(Z.shape)).astype(int)

R_start = np.zeros(len(shape)).astype(int)
R_stop  = np.array(list(shape)).astype(int)
Z_start = (P - Rs // 2)
Z_stop  = (P + Rs // 2) + Rs % 2

R_start = (R_start - np.minimum(Z_start, 0)).tolist()
Z_start = (np.maximum(Z_start, 0)).tolist()
R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop - Zs, 0))).tolist()
Z_stop = (np.minimum(Z_stop, Zs)).tolist()

r = [slice(start,stop) for start, stop in zip(R_start, R_stop)]
z = [slice(start,stop) for start, stop in zip(Z_start, Z_stop)]
R[r] = Z[z]
print(Z)
print(R)
# possible output
# [[7 5 2 1 3 8 5 0 8 2]
#  [7 4 8 9 7 7 0 7 3 7]
#  [1 5 5 6 0 6 9 4 5 8]
#  [1 5 3 4 7 8 1 1 2 4]
#  [6 2 1 4 6 4 1 7 7 2]
#  [2 4 8 9 3 2 2 1 8 0]
#  [9 8 9 4 8 3 7 1 5 5]
#  [0 5 1 3 5 9 4 8 0 9]
#  [1 6 9 7 1 2 4 4 6 2]
#  [2 1 7 7 7 1 7 9 8 9]]
# [[0 0 0 0 0]
#  [0 7 5 2 1]
#  [0 7 4 8 9]
#  [0 1 5 5 6]
#  [0 1 5 3 4]]
(81) Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], …, [11,12,13,14]]?
Z = np.arange(1, 15, dtype=np.uint32)
R = np.lib.stride_tricks.as_strided(Z, (11, 4), (4, 4))
print(R)
# [[ 1  2  3  4]
#  [ 2  3  4  5]
#  [ 3  4  5  6]
#  [ 4  5  6  7]
#  [ 5  6  7  8]
#  [ 6  7  8  9]
#  [ 7  8  9 10]
#  [ 8  9 10 11]
#  [ 9 10 11 12]
#  [10 11 12 13]
#  [11 12 13 14]]
(82) Compute a matrix rank
Z = np.random.uniform(0, 1, (10, 10))
U, S, V = np.linalg.svd(Z) # Singular Value Decomposition
rank = np.sum(S > 1e-10)
print(rank)
(83) How to find the most frequent value in an array?
Z = np.random.randint(0, 10, 50)
print(np.bincount(Z).argmax())
(84) Extract all the contiguous 3x3 blocks from a random 10x10 matrix
Z = np.random.randint(0, 5, (10, 10))
n = 3
i = 1 + (Z.shape[0] - 3)
j = 1 + (Z.shape[1] - 3)
C = np.lib.stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides)
print(C)
(85) Create a 2D array subclass such that Z[i,j] == Z[j,i]
# Note: only works for 2d array and value setting using indices
class Symetric(np.ndarray):
    def __setitem__(self, index, value):
        i,j = index
        super(Symetric, self).__setitem__((i,j), value)
        super(Symetric, self).__setitem__((j,i), value)

def symetric(Z):
    return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric)

S = symetric(np.random.randint(0, 10, (5, 5)))
S[2, 3] = 42
print(S)
(86) Consider a set of p matrices wich shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once?
p, n = 10, 20
M = np.ones((p, n, n))
V = np.ones((p, n, 1))
S = np.tensordot(M, V, axes=[[0, 2], [0, 1]])
print(S)
# explanation
# for i in range(n):
#     for j in range(1):
#         for x in range(p):
#             for y in range(n):
#                 ans[i][j] += M[x, i, y] * V[x, y, j]
(87) Consider a 16x16 array, how to get the block-sum (block size is 4x4)?
Z = np.ones((16, 16))
k = 4
S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),
                                    np.arange(0, Z.shape[1], k), axis=1)
print(S)
# [[ 16.  16.  16.  16.]
#  [ 16.  16.  16.  16.]
#  [ 16.  16.  16.  16.]
#  [ 16.  16.  16.  16.]]
(88) How to implement the Game of Life using numpy arrays?
def iterate(Z):
    # Count neighbours
    N = (Z[0:-2, 0:-2] + Z[0:-2, 1:-1] + Z[0:-2, 2:] + Z[1:-1, 0:-2]
         + Z[1:-1, 2:] + Z[2:, 0:-2] + Z[2:, 1:-1] + Z[2:, 2:])

    # Apply rules
    birth = (N == 3) & (Z[1:-1, 1:-1] == 0)
    survive = ((N == 2) | (N == 3)) & (Z[1:-1, 1:-1] == 1)
    Z[...] = 0
    Z[1:-1, 1:-1][birth | survive] = 1
    return Z

Z = np.random.randint(0, 2, (50, 50))
for i in range(100):
    Z = iterate(Z)
print(Z)
(89) How to get the n largest values of an array
Z = np.arange(10000)
np.random.shuffle(Z)
n = 5
# Slow
print(Z[np.argsort(Z)[-n:]])
# Fast
print(Z[np.argpartition(-Z, n)[:n]])
(90) Given an arbitrary number of vectors, build the cartesian product (every combinations of every item)
def cartesian(arrays):
    arrays = [np.asarray(a) for a in arrays]
    shape = (len(x) for x in arrays)
    ix = np.indices(shape, dtype=int)
    ix = ix.reshape(len(arrays), -1).T
    for n, arr in enumerate(arrays):
        ix[:, n] = arrays[n][ix[:, n]]
    return ix

print(cartesian(([1, 2, 3], [4, 5], [6, 7])))
# [[1 4 6]
#  [1 4 7]
#  [1 5 6]
#  [1 5 7]
#  [2 4 6]
#  [2 4 7]
#  [2 5 6]
#  [2 5 7]
#  [3 4 6]
#  [3 4 7]
#  [3 5 6]
#  [3 5 7]]
(91) How to create a record array from a regular array?
Z = np.array([("Hello", 2.5, 3),
              ("World", 3.6, 2)])
R = np.core.records.fromarrays(Z.T, names='col1, col2, col3',
                               formats='S8, f8, i8')
print(R)
# [('Hello',  2.5, 3) ('World',  3.6, 2)]
(92) Consider a large vector Z, compute Z to the power of 3 using 3 different methods
x = np.random.rand(10000)
%timeit np.power(x, 3)
%timeit x * x * x
%timeit np.einsum('i,i,i->i', x, x, x)
# 1000 loops, best of 3: 730 µs per loop
# 100000 loops, best of 3: 8.72 µs per loop
# 100000 loops, best of 3: 12.6 µs per loop
(93) Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B?
A = np.random.randint(0, 5, (8, 3))
B = np.random.randint(0, 5, (2, 2))
C = (A[..., np.newaxis, np.newaxis] == B)
rows = np.where(C.any((3,1)).all(1))[0]
print(rows)
(94) Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3])
Z = np.random.randint(0, 5, (10,3))
# solution for arrays of all dtypes (including string arrays and record arrays)
E = np.all(Z[:, 1:] == Z[:, :-1], axis=1)
U = Z[~E]
print(U)

# soluiton for numerical arrays only, will work for any number of columns in Z
U = Z[Z.max(axis=1) != Z.min(axis=1), :]
print(U)
(95) Convert a vector of ints into a matrix binary representation
I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128])
B = ((I.reshape(-1, 1) & (2 ** np.arange(8))) != 0).astype(int)
print(B[:, ::-1])
# [[0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 0 1]
#  [0 0 0 0 0 0 1 0]
#  [0 0 0 0 0 0 1 1]
#  [0 0 0 0 1 1 1 1]
#  [0 0 0 1 0 0 0 0]
#  [0 0 1 0 0 0 0 0]
#  [0 1 0 0 0 0 0 0]
#  [1 0 0 0 0 0 0 0]]

# another solution
I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8)
print(np.unpackbits(I[:, np.newaxis], axis=1))
# [[0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 0 1]
#  [0 0 0 0 0 0 1 0]
#  [0 0 0 0 0 0 1 1]
#  [0 0 0 0 1 1 1 1]
#  [0 0 0 1 0 0 0 0]
#  [0 0 1 0 0 0 0 0]
#  [0 1 0 0 0 0 0 0]
#  [1 0 0 0 0 0 0 0]]
(96) Given a two dimensional array, how to extract unique rows?
Z = np.random.randint(0, 2, (6, 3))
T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1])))
_, idx = np.unique(T, return_index=True)
uZ = Z[idx]
print(uZ)

# awkward method
Z = np.random.randint(0, 2, (6, 3))
uZ = map(lambda x:list(x), list(set(map(lambda x:tuple(x), list(Z)))))
print(uZ)
(97) Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function
# Reference : http://ajcr.net/Basic-guide-to-einsum/
A = [1, 2, 3]
B = [4, 5, 6]
print(np.einsum('i', A))
# [1 2 3]
print(np.einsum('i->', A))  # np.sum(A)
# 6
print(np.einsum('i,i->i', A, B))  # A * B
# [ 4 10 18]
print(np.einsum('i,i', A, B))  # np.inner(A, B)
# 32
print(np.einsum('i,j->ij', A, B))  # np.outer(A, B)
# [[ 4  5  6]
#  [ 8 10 12]
#  [12 15 18]]
(98) Considering a path described by two vectors (X,Y), how to sample it using equidistant samples?
phi = np.arange(0, 10 * np.pi, 0.1)
x = a * phi * np.cos(phi)
y = a * phi * np.sin(phi)

dr = (np.diff(x) ** 2 + np.diff(y) ** 2) ** .5
r = np.zeros_like(x)
r[1:] = np.cumsum(dr)
r_int = np.linspace(0, r.max(), 200)
x_int = np.interp(r_int, r, x)
y_int = np.interp(r_int, r, y)
(99) Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n.
X = np.asarray([[1.0, 0.0, 3.0, 8.0],
                [2.0, 0.0, 1.0, 1.0],
                [1.5, 2.5, 1.0, 0.0]])
n = 4
M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1)
M &= (X.sum(axis=-1) == n)
print(X[M])
# [[ 2.  0.  1.  1.]]
(100) Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means).
X = np.random.randn(100) # random 1D array
N = 1000 # number of bootstrap samples
idx = np.random.randint(0, X.size, (N, X.size))
means = X[idx].mean(axis=1)
confint = np.percentile(means, [2.5, 97.5])
print(confint)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值