Python数据分析基础

二、numpy100题练习

1.Import the numpy package under the name np (★☆☆)。
导入numpy库并简写为 np

代码如下:

import numpy as np  


2. Print the numpy version and the configuration (★☆☆)
打印numpy的版本和配置说明

代码如下:

import numpy as np  
print(np.__version__)
print(np.show_config())

输出结果如下:

1.19.1
blas_mkl_info:
  NOT AVAILABLE
blis_info:
  NOT AVAILABLE
openblas_info:
    library_dirs = ['D:\\a\\1\\s\\numpy\\build\\openblas_info']
    libraries = ['openblas_info']
    language = f77
    define_macros = [('HAVE_CBLAS', None)]
blas_opt_info:
    library_dirs = ['D:\\a\\1\\s\\numpy\\build\\openblas_info']
    libraries = ['openblas_info']
    language = f77
    define_macros = [('HAVE_CBLAS', None)]
lapack_mkl_info:
  NOT AVAILABLE
openblas_lapack_info:
    library_dirs = ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info']
    libraries = ['openblas_lapack_info']
    language = f77
    define_macros = [('HAVE_CBLAS', None)]
lapack_opt_info:
    library_dirs = ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info']
    libraries = ['openblas_lapack_info']
    language = f77
    define_macros = [('HAVE_CBLAS', None)]
None

Process finished with exit code 0


3.Create a null vector of size 10 (★☆☆)
创建一个长度为10的空向量

代码如下:

Z = np.zeros(10)
print(Z)

输出结果如下:

[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]


4. How to find the memory size of any array (★☆☆)
如何找到任何一个数组的内存大小

代码如下:

Z = np.zeros((10, 10))
print("%d bytes" % (Z.size * Z.itemsize))

输出结果如下:

800 bytes


5. How to get the documentation of the numpy add function from the command line? (★☆☆)
如何从命令行得到numpy中add函数的说明文档?

代码如下:

cmd命令行用如下命令:
python -c "import numpy; numpy.info(numpy.add)"
python程序中使用如下代码:
print(np.info(np.add))

输出结果如下:

add(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])

Add arguments element-wise.

Parameters
----------
x1, x2 : array_like
    The arrays to be added.
    If ``x1.shape != x2.shape``, they must be broadcastable to a common
    shape (which becomes the shape of the output).
out : ndarray, None, or tuple of ndarray and None, optional
    A location into which the result is stored. If provided, it must have
    a shape that the inputs broadcast to. If not provided or None,
    a freshly-allocated array is returned. A tuple (possible only as a
    keyword argument) must have length equal to the number of outputs.
where : array_like, optional
    This condition is broadcast over the input. At locations where the
    condition is True, the `out` array will be set to the ufunc result.
    Elsewhere, the `out` array will retain its original value.
    Note that if an uninitialized `out` array is created via the default
    ``out=None``, locations within it where the condition is False will
    remain uninitialized.
**kwargs
    For other keyword-only arguments, see the
    :ref:`ufunc docs <ufuncs.kwargs>`.

Returns
-------
add : ndarray or scalar
    The sum of `x1` and `x2`, element-wise.
    This is a scalar if both `x1` and `x2` are scalars.

Notes
-----
Equivalent to `x1` + `x2` in terms of array broadcasting.

Examples
--------
>>> np.add(1.0, 4.0)
5.0
>>> x1 = np.arange(9.0).reshape((3, 3))
>>> x2 = np.arange(3.0)
>>> np.add(x1, x2)
array([[  0.,   2.,   4.],
       [  3.,   5.,   7.],
       [  6.,   8.,  10.]])


6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆)
创建一个长度为10并且除了第五个值为1的空向量

代码如下:

x = np.zeros(10)
x[4] = 1
print(x)

输出结果如下:

[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]

7.Create a vector with values ranging from 10 to 49 (★☆☆)
创建一个值域范围从10到49的向量

代码如下:

x = np.arange(10, 50)
print(x)

输出结果如下:

[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49]


8. Reverse a vector (first element becomes last) (★☆☆)
反转一个向量(第一个元素变为最后一个)

代码如下:

x = np.arange(50)
x = x[::-1]  # 当步长为 -1 即反向走时,应该从下标大的走向下标小的,开始反转
print(x)

输出结果如下:

[49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26
 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2
  1  0]


9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆)
创建一个 3x3 并且值从0到8的矩阵

代码如下:

x = np.arange(9).reshape(3, 3)
print(x)

输出结果如下:

[[0 1 2]
 [3 4 5]
 [6 7 8]]


10.Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆)
找到数组[1,2,0,0,4,0]中非0元素的位置索引

代码如下:

x = np.nonzero([1, 2, 0, 0, 4, 0])
print(x)

输出结果如下:

(array([0, 1, 4], dtype=int64),)


11.Create a 3x3 identity matrix (★☆☆)
​创建3x3的对角矩阵

代码如下:

x = np.eye(3)
print(x)

输出结果如下:

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

12.Create a 3x3x3 array with random values (★☆☆)
​创建一个 3x3x3的随机数组

代码如下:

x = np.random.random((3, 3, 3))
print(x)

输出结果如下:

[[[0.90645099 0.39055025 0.13326805]
  [0.82727578 0.80306489 0.73626431]
  [0.86937515 0.93136459 0.05317126]]

 [[0.57875347 0.6657227  0.24202423]
  [0.41064389 0.66225554 0.32342978]
  [0.22953023 0.25789695 0.3861879 ]]

 [[0.7715045  0.80144285 0.09692252]
  [0.64913309 0.21699249 0.42576076]
  [0.19170728 0.40928135 0.68654943]]]

Process finished with exit code 0

13.Create a 10x10 array with random values and find the minimum and maximum values (★☆☆)
创建一个 10x10 的随机数组并找到它的最大值和最小值

代码如下:

import numpy as np
x = np.random.random((10, 10))
print(x.min())
print(x.max())

输出结果如下:

0.004546019288869885
0.9988575624248186

14.Create a random vector of size 30 and find the mean value (★☆☆)
​创建一个长度为30的随机向量并找到它的平均值

代码如下:

x = np.random.random(30)
print(x.mean())

输出结果如下:

0.5570963332977725

15.Create a 2d array with 1 on the border and 0 inside (★☆☆)
​创建一个二维数组,其中边界值为1,其余值为0

代码如下:

x = np.ones((10, 10))
x[1:-1, 1:-1] = 0
print(x)

输出结果如下:

[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]

Process finished with exit code 0


16.How to add a border (filled with 0’s) around an existing array? (★☆☆)
​对于一个已知数组,如何添加一个用0填充的边界

代码如下:

x = np.ones((5, 5))
x = np.pad(x, pad_width=1, mode='constant', constant_values=0)
print(x)

输出结果如下:

[[0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0.]]

说明:np.pad(array, pad_width, mode, kwargs)
顾名思义,用于给数组array扩充新的行或者列。
参数意义:
array:要填充的对象
pad_width: 各个方向上填充的维度
pad_width = ((1,2), (2,2)) 指第一维(此时为行)上面填充一位、下面填充两位;第二维(此时为列)左边填充两位、右边填充两位。
mode:用于指定填充内容。

17.What is the result of the following expression? (★☆☆)
以下表达式运行的结果分别是什么

代码如下:

print(0 * np.nan)
print(np.nan == np.nan)
print(np.inf > np.nan)
print(np.nan - np.nan)
print(np.nan in set([np.nan]))
print(0.3 == 3 * 0.1)

输出结果如下:

nan
False
False
nan
True
False

说明:
nan与任何值进行运算都是 nan;
nan:not a number 表示不是一个数字,属于浮点类;
inf:np.inf 表示正无穷,-np.inf表示负无穷,属于浮点类;
两个nan是不相等的

18.Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆)
​创建一个 5x5的矩阵,并设置值1,2,3,4落在其对角线下方位置

代码如下:

x = np.diag(1 + np.arange(4), k=-1)
print(x)

输出结果如下:

[[0 0 0 0 0]
 [1 0 0 0 0]
 [0 2 0 0 0]
 [0 0 3 0 0]
 [0 0 0 4 0]]

说明:
numpy.diag(v,k=0)。以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换成方阵(非对角线元素为0).两种功能角色转变取决于输入的v。
参数详解:
v : array_like
如果v是2D数组,返回k位置的对角线。
如果v是1D数组,返回一个v作为k位置对角线的2维数组。
k : int, optional
对角线的位置,大于零位于对角线上面,小于零则在下面。

19.Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆)
​创建一个8x8 的矩阵,并且设置成棋盘样式

代码如下:

x = np.zeros((8, 8), dtype=int)
x[1::2, ::2] = 1
x[::2, 1::2] = 1
print(x)

输出结果如下:

[[0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]]

Process finished with exit code 0


说明:x[1::2, ::2] = 1。第一个切片表示行的数据变换,第二个表示第几行数据变换。1::2表示行的变化,从索引1开始,步长为2,赋值为1。后面::2,表示从第0行开始,步长为2,执行此赋值。
注意:格式b = a[i:j:s]
这里的s表示步进,缺省为1.(-1时即翻转读取)。
所以a[i:j:1]相当于a[i:j]。当s<0时,i缺省时,默认为-1. j缺省时,默认为-len(a)-1。所以a[::-1]相当于 a[-1:-len(a)-1:-1],也就是从最后一个元素到第一个元素复制一遍。

20.Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element?
考虑一个 (6,7,8) 形状的数组,其第100个元素的索引(x,y,z)是什么?

代码如下:

print(np.unravel_index(100, (6, 7, 8)))

输出结果如下:

(1, 5, 4)

说明:np.unravel_index(indices, shape, order = ‘C’)
一句话概括:求出数组某元素(或某组元素)拉成一维后的索引值在原本维度(或指定新维度)中对应的索引。
参数说明:
indices: 整数构成的数组, 其中元素是索引值(integer array whose elements are indices into flattened version of array)
shape: tuple of ints, 一般是原本数组的维度,也可以给定的新维度。

21.Create a checkerboard 8x8 matrix using the tile function (★☆☆)
用tile函数去创建一个 8x8的棋盘样式矩阵

代码如下:

x = np.tile(np.array([[0, 1], [1, 0]]), (4, 4))
print(x)

输出结果如下:

[[0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]]

Process finished with exit code 0

说明:np.tile(a,(2,1)),tile有平铺的意思,顾名思义。第一个参数为Y轴(纵向)扩大倍数,第二个为X轴(横向)扩大倍数。本例中X轴扩大一倍便为不复制。

22.Normalize a 5x5 random matrix (★☆☆)
对一个5x5的随机矩阵做归一化

代码如下:

x = np.random.random((5, 5))
x = (x-np.mean(x))/(np.std(x))
print(x)

输出结果如下:

[[ 0.59892254 -0.60850328 -1.67865401 -0.46662041  0.41723656]
 [-1.05768562 -1.02476268 -0.04168865 -0.44227418 -0.17553817]
 [-1.45474513  0.41247651 -0.28695422 -0.09156237  0.00757391]
 [-1.36155231 -0.08620354  0.538985    1.18103188 -0.59021046]
 [ 2.33106887 -0.45919266  1.54971195  1.8721533   0.91698717]]

说明:np.std(x)计算总体标准差。


23.Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆)
创建一个将颜色描述为(RGBA)四个无符号字节的自定义dtype?

代码如下:

color = np.dtype([("r", np.ubyte, 1),
                 ("g", np.ubyte, 1),
                 ("b", np.ubyte, 1),
                  ("a", np.ubyte, 1)])


24.Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆)
一个5x3的矩阵与一个3x2的矩阵相乘,实矩阵乘积是什么?

代码如下:

x = np.dot(np.ones((5, 3)), np.ones((3, 2)))
print(x)
或者使用下面代码:
x = np.ones((5, 3)) @ np.ones((3,2))   # python3.5以上版本
print(x)

输出结果如下:

[[3. 3.]
 [3. 3.]
 [3. 3.]
 [3. 3.]
 [3. 3.]]


25.Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆)
给定一个一维数组,对其在3到8之间的所有元素取反

代码如下:

x = np.arange(11)
x[(3 < x) & (x <= 8)] *= -1
print(x)

输出结果如下:

[ 0  1  2  3 -4 -5 -6 -7 -8  9 10]


26.What is the output of the following script? (★☆☆)
下面脚本运行后的结果是什么?

代码如下:

print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))

输出结果如下:

9
10

说明:

  • numpy.sum()签名如下(省略一些参数):numpy.sum(a, axis=None, dtype=None, out=None, …)
  • Python的sum签名:sum(iterable, start=0)
    sum对提供的可迭代对象进行迭代,对值求和,然后加-1(即减1)。 numpy.sum只是将提供的iterable中的所有值求和,并接收一个axis参数1。

27.Consider an integer vector Z, which of these expressions are legal? (★☆☆)
考虑一个整数向量Z,下列表达合法的是哪个

代码如下:

Z**Z
2 << Z >> 2
Z <- Z
1j*Z
Z/1/1
Z<Z>Z

解答:写个例子一个个试试。

Z = np.arange(5)
Z**Z    # legal

Z = np.arange(5)
2 << Z >> 2   # legal


Z = np.arange(5)
Z <- Z    # legal

Z = np.arange(5)
1j*Z      # legal

Z = np.arange(5)
Z/1/1     # legal

Z = np.arange(5)
Z<Z>Z      # false
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()


28.What are the result of the following expressions?
下列表达式的结果分别是什么?

代码如下:

np.array(0) / np.array(0)
np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float)

输出结果如下:

nan
0
[-2.14748365e+09]

29.How to round away from zero a float array ? (★☆☆)
如何从零位对浮点数组做舍入

代码如下:

x = np.random.uniform(-10, +10, 10)
print(np.copysign(np.ceil(np.abs(x)), x))

输出结果如下:

[  5.   4. -10.   7.  -9.   2.   6.   8.   6.  -1.]

说明:np.copysign(x1, x2)按元素将 x1 的符号更改为 x2 的符号。

30.How to find common values between two arrays? (★☆☆)
如何找到两个数组中的共同元素?

代码如下:

x = np.random.randint(0, 10, 10)
y = np.random.randint(0, 10, 10)
print(np.intersect1d(x, y))

输出结果如下:

[0 3 6 8 9]

说明:numpy.intersect1d(ar1, ar2, assume_unique=False, return_indices=False)[source]
返回两个数组中共同的元素。

  • ar1, ar2 : array_like
    Input arrays. Will be flattened if not already 1D.

  • assume_unique : bool
    If True, the input arrays are both assumed to be unique, which can speed up the calculation. Default is False.
    默认是False,如果是True,假定输入的数组中元素

  • return_indices : bool
    If True, the indices which correspond to the intersection of the two arrays are returned. The first instance of a value is used if there are multiple. Default is False.默认是False,如果是True,返回共同元素的索引位置,因为返回共同元素是排序后的,所以索引位置是排序后的元素位置。如果共同元素在一个数组中有多次出现,只返回第一次出现的索引位置


31.How to ignore all numpy warnings (not recommended)? (★☆☆)
如何忽略所有的 numpy 警告(尽管不建议这么做)

代码如下:

defaults = np.seterr(all="ignore")
Z = np.ones(1) / 0


32. Is the following expressions true? (★☆☆)
下面的表达式是正确的吗?

代码如下:

np.sqrt(-1) == np.emath.sqrt(-1)

print(np.sqrt(-1) == np.emath.sqrt(-1))

输出结果如下:

False


33.How to get the dates of yesterday, today and tomorrow? (★☆☆)
如何得到昨天,今天,明天的日期

代码如下:

yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D')
today = np.datetime64('today', 'D')
tomorrow = np.datetime64('today', 'D') + np.timedelta64(1, 'D')
print("yesterday is " + str(yesterday))
print('today is ' + str(today))
print('tomorrow is ' + str(tomorrow))

输出结果如下:

yesterday is 2021-06-25
today is 2021-06-26
tomorrow is 2021-06-27


34.How to get all the dates corresponding to the month of July 2016? (★★☆)
如何得到所有与2016年7月对应的所有日期

代码如下:

x = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
print(x)

输出结果如下:

['2016-07-01' '2016-07-02' '2016-07-03' '2016-07-04' '2016-07-05'
 '2016-07-06' '2016-07-07' '2016-07-08' '2016-07-09' '2016-07-10'
 '2016-07-11' '2016-07-12' '2016-07-13' '2016-07-14' '2016-07-15'
 '2016-07-16' '2016-07-17' '2016-07-18' '2016-07-19' '2016-07-20'
 '2016-07-21' '2016-07-22' '2016-07-23' '2016-07-24' '2016-07-25'
 '2016-07-26' '2016-07-27' '2016-07-28' '2016-07-29' '2016-07-30'
 '2016-07-31']

Process finished with exit code 0


35.How to compute ((A+B)(-A/2)) in place (without copy)? (★★☆)
如何直接在位计算(A+B)
(-A/2)(不建立副本)

代码如下:

A = np.ones(3) * 1
B = np.ones(3) * 2
C = np.ones(3) * 3
np.add(A, B, out=B)
np.divide(A, 2, out=A)
np.negative(A, out=A)
np.multiply(A, B, out=A)
print(A)

输出结果如下:

[-1.5 -1.5 -1.5]

36.Extract the integer part of a random array using 5 different methods (★★☆)
用五种不同的方法去提取一个随机数组的整数部分

代码如下:

x = np.random.uniform(0, 10, 10)
print(x)
print(x - x % 1)
print(np.floor(x))
print(np.ceil(x) - 1)
print(x.astype(int))
print(np.trunc(x))

输出结果如下:

[0.83886482 8.68873834 0.2831072  7.92827185 6.83838349 2.63565649
 1.08767908 9.24449244 0.29156509 5.41644904]
[0. 8. 0. 7. 6. 2. 1. 9. 0. 5.]
[0. 8. 0. 7. 6. 2. 1. 9. 0. 5.]
[0. 8. 0. 7. 6. 2. 1. 9. 0. 5.]
[0 8 0 7 6 2 1 9 0 5]
[0. 8. 0. 7. 6. 2. 1. 9. 0. 5.]

Process finished with exit code 0

37.Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆)
创建一个5x5的矩阵,其中每行的数值范围从0到4

代码如下:

x = np.zeros((5, 5))
x += np.arange(5)
print(x)

输出结果如下:

[[0. 1. 2. 3. 4.]
 [0. 1. 2. 3. 4.]
 [0. 1. 2. 3. 4.]
 [0. 1. 2. 3. 4.]
 [0. 1. 2. 3. 4.]]

Process finished with exit code 0


38.Consider a generator function that generates 10 integers and use it to build an array (★☆☆)
通过考虑一个可生成10个整数的函数,来构建一个数组

代码如下:

def generate():
    for x in range(10):
        yield x
y = np.fromiter(generate(), dtype=float, count=-1)
print(y)

输出结果如下:

[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]


说明:numpy.fromiter(iterable, dtype, count = - 1)
iterable,可迭代:表示可迭代对象。
dtype:代表结果数组项的数据类型。
count:代表要从数组缓冲区中读取的项目数,默认为-1表示取所有数据。
yield的作用是将一个函数转换成一个迭代器,并且程序再次进入这个函数时候,是从这个函数的yield语句的下一句开始执行的。


39.Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆)
创建一个长度为10的随机向量,其值域范围从0到1,但是不包括0和1

代码如下:

x = np.linspace(0, 1, 11, endpoint=False)[1:]
print(x)

输出结果如下:

[0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 0.54545455
 0.63636364 0.72727273 0.81818182 0.90909091]

说明:
def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数说明:
start:起始点
stop:终止点
num : int, optional,默认50,生成start和stop之间50个等差间隔的元素
endpoint : 生成等差间隔的元素,但是不包含stop,即间隔为 (stop - start)/num
retstep :返回一个(array,num)元组,array是结果数组,num是间隔大小
dtype : 输出数组的类型。如果没有给出dtype,则从其他输入参数推断数据类型。

40.Create a random vector of size 10 and sort it (★★☆)
​创建一个长度为10的随机向量,并将其排序

代码如下:

x = np.random.random(10)
x.sort()
print(x)

输出结果如下:

[0.18131185 0.18264162 0.24828664 0.30911976 0.57123364 0.6794581
 0.82297437 0.84905751 0.8846586  0.98016983]

41.How to sum a small array faster than np.sum? (★★☆)
​对于一个小数组,如何用比 np.sum更快的方式对其求和

代码如下:

x = np.arange(10)
print(np.add.reduce(x))

输出结果如下:

45

说明:np.add.reduce(x)此用法和sum类似,只是该方法只是适用于小型的矩阵方法

42.Consider two random array A and B, check if they are equal (★★☆)
​对于两个随机数组A和B,检查它们是否相等

代码如下:

x = np.random.randint(0, 2, 5)
y = np.random.randint(0, 2, 5)
equal = np.allclose(x, y)
# 也可以用代码:equal = np.array_equal(x, y)
print(equal)

输出结果如下:

False

43.Make an array immutable (read-only) (★★☆)
创建一个不可变数组(只读)

代码如下:

x = np.zeros(10)
x.flags.writeable = False
x[0] = 1

如果赋值,报错输出结果如下:

Traceback (most recent call last):
  File "D:/dream/Test.py", line 9, in <module>
    x[0] = 1
ValueError: assignment destination is read-only

44.Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆)
​将笛卡尔坐标下的一个10x2的矩阵转换为极坐标形式

代码如下:

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)

输出结果如下:

[1.00119376 0.6062515  0.9647493  1.20190711 1.18943819 0.36343525
 1.15122744 0.84961144 0.61625633 0.80168848]
[1.2218046  1.07121872 1.16437079 0.73602919 0.9208638  1.09714694
 0.54559932 0.86118137 1.02290245 0.80916411]

Process finished with exit code 0

45.Create random vector of size 10 and replace the maximum value by 0 (★★☆)
​创建一个长度为10的向量,并将向量中最大值替换为0

代码如下:

x = np.random.random(10)
print(x)
x[x.argmax()] = 0
print(x)

输出结果如下:

[0.94209034 0.74879552 0.40448461 0.93907565 0.22411149 0.57168291
 0.21678106 0.58414904 0.50646311 0.63689233]
[0.         0.74879552 0.40448461 0.93907565 0.22411149 0.57168291
 0.21678106 0.58414904 0.50646311 0.63689233]

Process finished with exit code 0


46.Create a structured array with x and y coordinates covering the [0,1]x[0,1] area (★★☆)
​ 创建一个结构化数组,并实现 x 和 y 坐标覆盖 [0,1]x[0,1] 区域

代码如下:

Z = np.zeros((5, 5), [('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.  )]]

Process finished with exit code 0

说明:meshgrid函数通常使用在数据的矢量化上。它适用于生成网格型数据,可以接受两个一维数组生成两个二维矩阵,对应两个数组中所有的(x,y)对。

47.Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj))
​给定array X 和 Y, 构造柯西矩阵C

代码如下:

x = np.arange(8)
y = x + 0.5
c = 1.0 / np.subtract.outer(x, y)
print(np.linalg.det(c))

输出结果如下:

3638.163637117973

说明:np.subtract.outer(b,a)是b[:,None]-a的函数对应
其含义是:有两个向量a、b,要实现a中的每个元素与b中的每个元素进行比较。
np.linalg.det():矩阵求行列式

48.Print the minimum and maximum representable value for each numpy scalar type (★★☆)
​打印每个numpy标量类型的最小值和最大值

代码如下:

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.4028235e+38
3.4028235e+38
1.1920929e-07
-1.7976931348623157e+308
1.7976931348623157e+308
2.220446049250313e-16

Process finished with exit code 0

说明:numpy.iinfo()函数显示整数类型的机器限制。numpy.finfo()函数显示浮点类型的机器限制。eps是一个很小的非负数,除法的分母不能为0的,不然会直接跳出显示错误。使用eps将可能出现零,使用eps来替换,这样不会报错。
用法: numpy.iinfo(dtype),np.finfo(dtype)

49.How to print all the values of an array? (★★☆)
​如何打印一个数组中的所有数值?

代码如下:

import sys
np.set_printoptions(threshold=sys.maxsize)
Z = np.zeros((16, 16))
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. 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. 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. 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. 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. 0. 0. 0. 0. 0. 0.]]

Process finished with exit code 0


说明:np.set_printoptions(threshold=np.nan)会引起错误,语句改成np.set_printoptions(threshold=sys.maxsize)解决了这个简单的问题。
set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, suppress=None, nanstr=None, infstr=None),控制输出方式。
参数解释:
precision:控制输出的小数点个数,默认是8
threshold:控制输出的值的个数,其余以…代替;
当设置打印显示方式threshold=np.nan,意思是输出数组的时候完全输出,不需要省略号将中间数据省略
suppress: 当suppress=True,表示小数不需要以科学计数法的形式输出


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])

输出结果如下:

39

51.Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆)
创建一个表示位置(x,y)和颜色(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 (★★☆)
​对一个表示坐标形状为(100,2)的随机向量,找到点与点的距离

代码如下:

方法一:
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
# Thanks Gavin Heverly-Coulson (#issue 1)
import scipy.spatial
Z = np.random.random((10,2))
D = scipy.spatial.distance.cdist(Z,Z)
print(D)

输出结果如下:

[[0.         0.62943401 0.40932575 0.99851866 0.42288086 0.60303426
  0.59532926 0.87293245 0.26721201 0.2684066 ]
 [0.62943401 0.         0.30829421 0.95541649 0.20737901 0.03112006
  0.60165853 0.41815889 0.51448669 0.84625501]
 [0.40932575 0.30829421 0.         1.09285323 0.16290345 0.29633276
  0.68210887 0.69316361 0.43754461 0.66953205]
 [0.99851866 0.95541649 1.09285323 0.         0.93876534 0.9331862
  0.4200548  0.66614433 0.74303778 0.93959812]
 [0.42288086 0.20737901 0.16290345 0.93876534 0.         0.18290375
  0.53642662 0.54076005 0.34708045 0.65027082]
 [0.60303426 0.03112006 0.29633276 0.9331862  0.18290375 0.
  0.57399473 0.41392255 0.48359547 0.81685097]
 [0.59532926 0.60165853 0.68210887 0.4200548  0.53642662 0.57399473
  0.         0.48727935 0.33064309 0.60198292]
 [0.87293245 0.41815889 0.69316361 0.66614433 0.54076005 0.41392255
  0.48727935 0.         0.64460599 0.99979715]
 [0.26721201 0.51448669 0.43754461 0.74303778 0.34708045 0.48359547
  0.33064309 0.64460599 0.         0.35942761]
 [0.2684066  0.84625501 0.66953205 0.93959812 0.65027082 0.81685097
  0.60198292 0.99979715 0.35942761 0.        ]]

Process finished with exit code 0



说明:np.atleast_2d(*arys)将输入视为至少具有两个维度的数组。
参数arys1, arys2…:一个或多个类似数组的序列。非数组输入被转换为数组。已经有两个或更多维度的数组被保留。
返回值:一个数组或数组列表,每个数组都有. 尽可能避免复制,并返回具有两个或更多维度的视图。
scipy.spatial.distance.cdist(X1, X2, metric=‘euclidean’, p=None, V=None, VI=None, w=None),该函数用于计算两个输入集合的距离,通过metric参数指定计算距离的不同方式得到不同的距离度量值。

53.How to convert a float (32 bits) array into an integer (32 bits) in place?
​如何将32位的浮点数(float)转换为对应的整数(integer)

代码如下:

x = np.arange(10, dtype=np.float32)
x = x.astype(np.int32, copy=False)
print(x)

输出结果如下:

[0 1 2 3 4 5 6 7 8 9]

54 How to read the following file? (★★☆)
如何读取以下文件

1, 2, 3, 4, 5
6,  ,  , 7, 8
 ,  , 9,10,11

​代码如下:

#Fake file
s = StringIO("""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]]

说明:很多时候,数据读写不一定是文件,也可以在内存中读写。StringIO就是在内存中读写str。要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可。
numpy.genfromtxt(),主要执行两个循环运算。第一个循环将文件的每一行转换成字符串序列。第二个循环将每个字符串序列转换为相应的数据类型。其能够考虑缺失的数据,但其他更快和更简单的函数向loadtxt不能考虑缺失值。

55.What is the equivalent of enumerate for numpy arrays? (★★☆)
对于numpy数组,enumerate的等价操作是什么?

​解答:enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。用法:enumerate(sequence, [start=0])

​代码如下:

x = np.arange(9).reshape((3, 3))
for index, value in np.ndenumerate(x):
    print(index, value)

for index in np.ndindex(x.shape):
    print(index, x[index])

运行结果如下:

(0, 0) 0
(0, 1) 1
(0, 2) 2
(1, 0) 3
(1, 1) 4
(1, 2) 5
(2, 0) 6
(2, 1) 7
(2, 2) 8
(0, 0) 0
(0, 1) 1
(0, 2) 2
(1, 0) 3
(1, 1) 4
(1, 2) 5
(2, 0) 6
(2, 1) 7
(2, 2) 8

56.Generate a generic 2D Gaussian-like array (★★☆)
​生成二维高斯分布

代码如下:

X, Y = np.meshgrid(np.linspace(-1, 1, 10), np.linspace(-1, 1, 10))
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)

运行结果如下:

[[0.36787944 0.44822088 0.51979489 0.57375342 0.60279818 0.60279818
  0.57375342 0.51979489 0.44822088 0.36787944]
 [0.44822088 0.54610814 0.63331324 0.69905581 0.73444367 0.73444367
  0.69905581 0.63331324 0.54610814 0.44822088]
 [0.51979489 0.63331324 0.73444367 0.81068432 0.85172308 0.85172308
  0.81068432 0.73444367 0.63331324 0.51979489]
 [0.57375342 0.69905581 0.81068432 0.89483932 0.9401382  0.9401382
  0.89483932 0.81068432 0.69905581 0.57375342]
 [0.60279818 0.73444367 0.85172308 0.9401382  0.98773022 0.98773022
  0.9401382  0.85172308 0.73444367 0.60279818]
 [0.60279818 0.73444367 0.85172308 0.9401382  0.98773022 0.98773022
  0.9401382  0.85172308 0.73444367 0.60279818]
 [0.57375342 0.69905581 0.81068432 0.89483932 0.9401382  0.9401382
  0.89483932 0.81068432 0.69905581 0.57375342]
 [0.51979489 0.63331324 0.73444367 0.81068432 0.85172308 0.85172308
  0.81068432 0.73444367 0.63331324 0.51979489]
 [0.44822088 0.54610814 0.63331324 0.69905581 0.73444367 0.73444367
  0.69905581 0.63331324 0.54610814 0.44822088]
 [0.36787944 0.44822088 0.51979489 0.57375342 0.60279818 0.60279818
  0.57375342 0.51979489 0.44822088 0.36787944]]

Process finished with exit code 0


57.How to randomly place p elements in a 2D array? (★★☆)
​对一个二维数组,如何在其内部随机放置p个元素

代码如下:

n = 10
p = 3
Z = np.zeros((n, n))
np.put(Z, np.random.choice(range(n*n), p, replace=False), 1)
print(Z)

运行结果如下:

[[0. 0. 0. 0. 0. 0. 1. 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. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]

Process finished with exit code 0


说明:np.put(a, ind, v, mode=‘raise’),用给定值替换数组的指定元素。
参数解释 :
1、a 就是目标数组 这里就是10*10的零数组
2、ind是目标数组的位置
3、v是你要加入的值

再看numpy.random.choice(a, size=None, replace=True, p=None)
参数解释:
1、从a(只要是ndarray都可以,但必须是一维的)中随机抽取数字
2、size:取得数字的个数
2、replace:True表示可以取相同数字,False表示不可以取相同数字
3、数组p:描述数组a中每一个元素取得的概率。

58.Subtract the mean of each row of a matrix (★★☆)
​减去一个矩阵中的每一行的平均值

代码如下:

x = np.random.rand(5, 10)   # 五行十列
y = x - x.mean(axis=1, keepdims=True)
print(y)

运行结果如下:

[[-0.4392353  -0.33729231  0.40871144  0.1857524  -0.21741911 -0.34307837
   0.44400421  0.29894611  0.42390735 -0.42429644]
 [-0.24523748 -0.33950036  0.06688256  0.02660567  0.25348156  0.42125022
  -0.40010145  0.53583584 -0.15422919 -0.16498736]
 [ 0.13037981 -0.41325191  0.37747797  0.03508472  0.18893361  0.34493854
  -0.36462695  0.30393187 -0.2130418  -0.38982586]
 [ 0.57813253  0.09371932 -0.11876644 -0.1614628  -0.32419642 -0.14425195
   0.54174856  0.07489227 -0.31350617 -0.22630891]
 [ 0.0253086  -0.28838538  0.50789445 -0.2911425  -0.21058151 -0.04117407
  -0.08281602  0.46663116 -0.36129375  0.27555902]]

Process finished with exit code 0



说明:
axis=0表示输出矩阵是1行,也就是求每一列的平均值。
axis=1表示输出矩阵是1列, 也就是求每一行的平均值;
实际上这个axis=0就是选择shape中第一个元素(即第一维)变为1,axis=1就是选择shape中第二个元素变为1。用shape来看会比较方便。

59.How to sort an array by the nth column? (★★☆)
​如何通过第n列对一个数组进行排序

代码如下:

x = np.random.randint(0, 10, (3, 3))
print(x)
print(x[x[:, 1].argsort()])

运行结果如下:

[[5 6 9]
 [8 2 8]
 [2 1 0]]
[[2 1 0]
 [8 2 8]
 [5 6 9]]

说明:argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出。利用argsort函数求出第n列索引(按照从小到大顺序排出)再,利用切片排序节课

60.How to tell if a given 2D array has null columns? (★★☆)
​如何检查一个二维数组是否有空列

代码如下:

x = np.random.randint(0, 3, (3, 10))
print((~x.any(axis=0)).any())

运行结果如下:

False

61.Find the nearest value from a given value in an array (★★☆)
​从数组中的给定值中找出最近的值

代码如下:

x = np.random.uniform(0, 1, 10)
y = 0.5
m = x.flat[np.abs(x-y).argmin()]
print(m)

运行结果如下:

0.5390913336591108

说明:flat返回的是一个迭代器,可以用for访问数组每一个元素。然后通过argmin找出值最小的索引,并输出该值。

62 Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆)
​如何用迭代器(iterator)计算两个分别具有形状(1,3)和(3,1)的数组?

代码如下:

x = np.arange(3).reshape(3, 1)
y = np.arange(3).reshape(1, 3)
it = np.nditer([x, y, 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 (★★☆)
​创建一个具有name属性的数组类

代码如下:

class NameArray(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")
        
x = NameArray(np.arange(10), "range_10")
print(x.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)? (★★★)
​考虑一个给定的向量,如何对由第二个向量索引的每个元素加1(小心重复的索引)

代码如下:

x = np.ones(10)
I = np.random.randint(0, len(x), 20)
x += np.bincount(I, minlength=len(x))
print(x)

运行结果如下:

[4. 4. 5. 3. 4. 2. 3. 2. 1. 2.]

说明:np.bincount计算I中的0,1,2,3,…9出现的频次。最后和x求和即为所得。

65.How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★)
​根据索引列表(I),如何将向量(X)的元素累加到数组(F)

代码如下:

X = [1, 2, 3, 4, 5, 6]
I = [1, 3, 9, 3, 4, 1]
print(np.bincount(I))
F = np.bincount(I, X)
print(F)

运行结果如下:

[0. 7. 0. 6. 5. 0. 0. 0. 0. 3.]

说明:I中0出现了0次,1出现了两次分别在索引0和索引5,故bincount函数计算F=X[0]+X[5].以此类推。

66.Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★★)
​考虑一个(dtype=ubyte) 的 (w,h,3)图像,计算其唯一颜色的数量

代码如下:

w, h = 16, 16
I = np.random.randint(0, 2, (h, w, 3)).astype(np.ubyte)
F = I[..., 0] * [256*256]+ I[..., 1]*256 + I[..., 2]
n = len(np.unique(F))
print(n)

运行结果如下:

8

67.Considering a four dimensions array, how to get sum over the last two axis at once? (★★★)
​考虑一个四维数组,如何一次性计算出最后两个轴(axis)的和

代码如下:

A = np.random.randint(0, 10, (3, 4, 3, 4))
# 方法一
sum = A.sum(axis=(-2, -1))
print(sum)
# 方法二
# print(A.shape[:-2] + (-1,))     # 变成三维(3, 4, -1)
# print(A.reshape(A.shape[:-2] + (-1,)))   # 四维降为三维
sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1)  # 取最后一列求和即可
print(sum)

运行结果如下:

[[58 57 41 45]
 [32 40 57 54]
 [68 49 56 48]]
[[58 57 41 45]
 [32 40 57 54]
 [68 49 56 48]]

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,如何使用相同大小的向量S来计算D子集的均值

代码如下:

D = np.random.uniform(0, 1, 100)
S = np.random.randint(0, 10, 100)
D_sums = np.bincount(S, weights=D)
print(D_sums)
D_counts = np.bincount(S)
print(D_counts)
D_means = D_sums / D_counts
print(D_means)

运行结果如下:

[3.3503499  4.52270149 4.42856043 3.68164781 5.04815131 5.84234541
 5.59122446 9.17495567 4.03031571 4.82140861]
[ 8  9 11  7  9 12  9 17  9  9]
[0.41879374 0.50252239 0.4025964  0.52594969 0.5609057  0.48686212
 0.62124716 0.53970327 0.44781286 0.53571207]

也可以使用pandas库求解;

代码如下:

D = np.random.uniform(0, 1, 100)
S = np.random.randint(0, 10, 100)
print(pd.Series(D).groupby(S).mean())

输出结果如下:

0    0.349248
1    0.454959
2    0.543046
3    0.430920
4    0.415322
5    0.571532
6    0.697838
7    0.530791
8    0.658336
9    0.505136
dtype: float64

Process finished with exit code 0


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))
print(np.diag(np.dot(A, B)))   # Slow version
print(np.sum(A*B.T, axis=1))   # fast version 
print(np.einsum("ij, ji->i", A, B))   # faster version,等价于A*B.T

输出结果如下:

[1.00403696 1.23357122 0.81734347 1.27297369 1.74576836]

说明:axis=1取行和。关于函数np.einsum()可以参考链接https://zhuanlan.zhihu.com/p/27739282
https://cloud.tencent.com/developer/article/1369762
一个很好的例子是矩阵乘法,它将行与列相乘,然后对乘积结果求和。对于两个二维数组A和B,矩阵乘法操作可以用np.einsum(‘ij,jk->ik’, A, B)完成。
这个字符串是什么意思?想象’ij,jk->ik’在箭头->处分成两部分。左侧部分标记输入数组的轴:’ij’标记A和’jk’标记B。字符串的右侧部分用字母“ik”标记单个输出数组的轴。也就是说,我们正在传入两个二维数组,获取一个新的二维数组。大致如下:
在这里插入图片描述

注意

print(np.dot(A, B))   # 矩阵乘法
print(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? (★★★)
​考虑一个向量[1,2,3,4,5],如何建立一个新的向量,在这个新向量中每个值之间有3个连续的零

代码如下:

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)


输出结果如下:

[1. 0. 0. 0. 2. 0. 0. 0. 3. 0. 0. 0. 4. 0. 0. 0. 5.]

71.Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★)
​考虑一个维度(5,5,3)的数组,如何将其与一个(5,5)的数组相乘

代码如下:

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)


输出结果如下:

[[[2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]]

 [[2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]]

 [[2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]]

 [[2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]]

 [[2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]
  [2. 2. 2.]]]


72 How to swap two rows of an array? (★★★)
​如何对一个数组中任意两行做交换

代码如下:

x = np.arange(25).reshape(5, 5)
x[[0, 1]] = x[[1, 0]]
print(x)


输出结果如下:

[[ 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 (★★★)
​使用10个三元数的集合描述10个三角形,找出组成这些三角形边的集合

代码如下:

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)


输出结果如下:

[( 2, 24) ( 2, 81) ( 3, 56) ( 3, 71) ( 6, 25) ( 6, 57) ( 6, 64) ( 6, 68)
 ( 7, 36) ( 7, 45) (11, 22) (11, 65) (12, 54) (12, 69) (22, 65) (24, 81)
 (25, 64) (36, 45) (46, 90) (46, 94) (54, 69) (54, 72) (54, 99) (56, 71)
 (57, 65) (57, 68) (65, 68) (72, 99) (90, 94)]


74.Given an array C that is a bincount, how to produce an array A such that np.bincount(A) == C? (★★★)
​给定一个二进制的数组C,如何产生一个数组A满足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]    # 3-19   3-190-17,求得连续三项和
    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]) (★★★)
​给定一维数组Z,构造一个二维数组,其第一行为Z[0],Z[1],Z[2]),下一行依次偏移1位,最后一行为(Z[-3],Z[-2],Z[-1])

代码如下:

def rolling(a, window):
    shape = (a.size - window + 1, window)
    strides = (a.itemsize, a.itemsize)  
    #itemsize输出array元素的字节数
    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]]


说明:numpy.lib.stride_tricks.as_strided(x, shape=None, strides=None, subok=False, writeable=True);x就是我们要分割的矩阵,可以当做是一个蓝图,shape,strides都是新矩阵的属性,也就是说这个函数按照给定的shape和strides来划分x,返回一个新的矩阵,最后两个参数不讨论,可以看numpy官方手册的描述。strides是numpy数组对象的一个属性,官方手册给出的解释是跨越数组各个维度所需要经过的字节数(bytes)。下方给出详细说明的链接:https://zhuanlan.zhihu.com/p/64933417
首先看第一个维度,0到1,1到2等之间距离都是4字节,再看第二个维度对应位置,0到1,1到2之间在原数组距离也是四个字节。

77 How to negate a boolean, or to change the sign of a float inplace? (★★★)
​如何对布尔值取反,或者原位(in-place)改变浮点数的符号(sign)

代码如下:

Z = np.random.randint(0, 2, 100)
print(np.logical_not(Z, out=Z))

x = np.random.uniform(-1.0, 1.0, 100)
print(np.negative(x, out=x))



输出结果如下:

[0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1
 1 1 1 0 1 1 0 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0 1 0 0 1 0 1 1 1 1 0
 1 1 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1]
[ 0.1415326  -0.80967232  0.05815041 -0.90465025  0.07611713 -0.88605864
  0.02166497  0.95891771  0.86204314  0.88798585  0.68008666 -0.82871234
  0.58801884  0.45734693  0.10714606  0.29343814 -0.54830853  0.42066699
 -0.95703258  0.98954916  0.34807745 -0.70377686 -0.88797778 -0.58724634
 -0.47633498  0.99384744  0.68577093  0.97651287 -0.32851027  0.36462885
  0.2694412  -0.99221083 -0.12190705  0.33933389 -0.44342584 -0.23717886
 -0.81807527 -0.20488381  0.13355686 -0.12250777  0.33968068  0.69525156
 -0.45915665  0.66402038 -0.0405786  -0.77833798  0.51945886  0.36617487
 -0.18975192 -0.61717756 -0.11813404  0.31630717 -0.3726119  -0.17210149
 -0.37431488  0.8560767  -0.35143798 -0.51347332  0.58762001 -0.39614005
  0.38168034 -0.73613966 -0.34881544  0.54307332  0.31504395 -0.83013609
  0.82851821 -0.94674003 -0.7577678  -0.04630179 -0.23783243 -0.17443552
  0.96180124 -0.95914897 -0.35009809  0.48698117  0.97947555 -0.0069084
 -0.08246425  0.24660944 -0.2371789  -0.15794197 -0.55041314 -0.24651259
  0.84933385  0.27142398  0.2329203  -0.43237379  0.39294333  0.13061459
  0.70060728  0.85693873 -0.95153677 -0.32421338 -0.6460425  -0.25700079
 -0.9281202   0.23659323 -0.61830298  0.64668119]

Process finished with exit code 0



说明:numpy.logical_not logical_not(x, *args, **kwargs):这是一个逻辑函数,可按元素计算NOT arr的真值。
numpy.negative(x[, out]) = <ufunc ‘negative’>
功能:对数组中每一个元素取相反数。

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])? (★★★)
​考虑两组点集P0和P1去描述一组线(二维)和一个点p,如何计算点p到每一条线 i (P0[i],P1[i])的距离

代码如下:

def distance(P0, P1, p):
    T = P1 - P0
    L = (T**2).sum(axis=1)   # 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))

输出结果如下:

[ 3.29183356 17.60240959  0.19493079  1.16592195  9.81198208  4.31248923
 12.53736236  2.05247654  4.23050097  9.80849193]

说明:

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])? (★★★)
​考虑两组点集P0和P1去描述一组线(二维)和一组点集P,如何计算每一个点 j(P[j]) 到每一条线 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, (10, 2))
print (np.array([distance(P0, P1, p_i) for p_i in p]))


输出结果如下:

[[ 5.70236576  6.98161946  6.82188759  1.94337899 12.1748486   1.73591168
   1.44628705  5.11034812 11.18864067  2.80270834]
 [ 4.37013585  0.03445049  1.63228978  8.84917772  0.25945996  0.76636648
  13.13419067  6.56747352  2.47467635  2.18106015]
 [ 8.48685566  7.57408423  6.64166954  1.33118425  9.10740408  4.63451568
   5.54615299  1.00195867 10.86262681  4.26343764]
 [ 3.711434    5.24635085  5.2696934   3.6827535  11.73385058  0.25447673
   1.20154717  5.36236417  9.67582606  0.91485908]
 [ 3.70939325  9.47796582 11.09750028 18.35941985  6.49161026  7.15626016
  17.20121221 10.60274137  6.95289532 11.43078345]
 [ 0.69444641  8.18939886 10.46333369 17.05442378  8.51339859  4.05827405
  20.31499438 13.7263355   6.44459164  9.43308137]
 [ 3.30290688  3.80253081  6.18977526 12.66619596  5.81478029  0.11854704
  18.95708395 12.38384745  2.2054508   5.06215844]
 [ 8.2801322   2.48162851  0.1847806   6.38661074  0.80391818  4.73545622
  15.58270943  9.02941636  4.16689823  0.90873081]
 [ 3.91578224  2.39567775  1.95099183 11.33293065  8.04759861  7.81735118
   2.3005111   4.29217089  2.55683407  6.95677313]
 [ 5.70003048  9.17171168  9.62956226  0.22999369 16.57687207  1.59630569
   3.04420129  9.59886992 14.10476953  4.21007294]]

Process finished with exit code 0


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)

输出结果如下:

[[9 9 9 9 0 9 8 6 3 4]
 [8 8 5 0 9 2 9 2 2 2]
 [5 9 8 3 5 9 3 7 9 8]
 [3 2 1 8 1 1 4 4 5 0]
 [5 6 2 8 6 7 5 2 0 4]
 [2 7 3 1 1 7 0 5 8 6]
 [1 1 5 1 1 1 2 0 0 2]
 [5 0 5 4 4 0 4 0 7 9]
 [8 3 9 8 0 6 5 6 8 4]
 [2 3 1 9 5 2 8 2 6 7]]
[[0 0 0 0 0]
 [0 9 9 9 9]
 [0 8 8 5 0]
 [0 5 9 8 3]
 [0 3 2 1 8]]

Process finished with exit code 0



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 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14],如何生成一个数组R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], …,[11,12,13,14]]

代码如下:

from numpy.lib import stride_tricks
Z = np.arange(1, 15, dtype=np.uint32)
R = 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]]

Process finished with exit code 0



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)

输出结果如下:

10

说明:

函数:np.linalg.svd(a,full_matrices=1,compute_uv=1)。
参数:
a是一个形如(M,N)矩阵
full_matrices的取值是为0或者1,默认值为1,这时u的大小为(M,M),v的大小为(N,N) 。否则u的大小为(M,K),v的大小为(K,N)K=min(M,N)。
compute_uv的取值是为0或者1,默认值为1,表示计算u,s,v。为0的时候只计算s。
返回值:
总共有三个返回值u,s,v
u大小为(M,M),s大小为(M,N),v大小为(N,N)A = u*s*v
其中s是对矩阵a的奇异值分解。s除了对角元素不为0,其他元素都为0,并且对角元素从大到小排列。s中有n个奇异值,一般排在后面的比较接近0,所以仅保留比较大的r个奇异值。

具体关于这个函数的解释可以看看这篇博客:https://blog.csdn.net/rainpasttime/article/details/79831533

83 How to find the most frequent value in an array?
​如何找到一个数组中出现频率最高的值

代码如下:

Z = np.random.randint(0, 10, 50)
print(np.bincount(Z).argmax())

输出结果如下:

0

84.Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★)
​从一个10x10的矩阵中提取出连续的3x3区块

代码如下:

from numpy.lib import stride_tricks
Z = np.random.randint(0, 5, (10, 10))
n = 3
i = 1 + (Z.shape[0]-3)
j = 1 + (Z.shape[1]-3)
C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides)
print(C)


输出结果如下:

[[[[3 4 3]
   [4 1 3]
   [0 0 4]]

  [[4 3 0]
   [1 3 3]
   [0 4 4]]

  [[3 0 1]
   [3 3 3]
   [4 4 3]]

  [[0 1 1]
   [3 3 3]
   [4 3 1]]

  [[1 1 1]
   [3 3 0]
   [3 1 2]]

  [[1 1 2]
   [3 0 2]
   [1 2 0]]

  [[1 2 0]
   [0 2 2]
   [2 0 2]]

  [[2 0 2]
   [2 2 4]
   [0 2 0]]]


 [[[4 1 3]
   [0 0 4]
   [0 0 3]]

  [[1 3 3]
   [0 4 4]
   [0 3 0]]

  [[3 3 3]
   [4 4 3]
   [3 0 1]]

  [[3 3 3]
   [4 3 1]
   [0 1 4]]

  [[3 3 0]
   [3 1 2]
   [1 4 2]]

  [[3 0 2]
   [1 2 0]
   [4 2 0]]

  [[0 2 2]
   [2 0 2]
   [2 0 4]]

  [[2 2 4]
   [0 2 0]
   [0 4 2]]]


 [[[0 0 4]
   [0 0 3]
   [0 2 1]]

  [[0 4 4]
   [0 3 0]
   [2 1 3]]

  [[4 4 3]
   [3 0 1]
   [1 3 4]]

  [[4 3 1]
   [0 1 4]
   [3 4 1]]

  [[3 1 2]
   [1 4 2]
   [4 1 1]]

  [[1 2 0]
   [4 2 0]
   [1 1 4]]

  [[2 0 2]
   [2 0 4]
   [1 4 1]]

  [[0 2 0]
   [0 4 2]
   [4 1 3]]]


 [[[0 0 3]
   [0 2 1]
   [0 0 4]]

  [[0 3 0]
   [2 1 3]
   [0 4 2]]

  [[3 0 1]
   [1 3 4]
   [4 2 0]]

  [[0 1 4]
   [3 4 1]
   [2 0 4]]

  [[1 4 2]
   [4 1 1]
   [0 4 3]]

  [[4 2 0]
   [1 1 4]
   [4 3 4]]

  [[2 0 4]
   [1 4 1]
   [3 4 4]]

  [[0 4 2]
   [4 1 3]
   [4 4 2]]]


 [[[0 2 1]
   [0 0 4]
   [3 2 4]]

  [[2 1 3]
   [0 4 2]
   [2 4 2]]

  [[1 3 4]
   [4 2 0]
   [4 2 3]]

  [[3 4 1]
   [2 0 4]
   [2 3 4]]

  [[4 1 1]
   [0 4 3]
   [3 4 4]]

  [[1 1 4]
   [4 3 4]
   [4 4 1]]

  [[1 4 1]
   [3 4 4]
   [4 1 0]]

  [[4 1 3]
   [4 4 2]
   [1 0 0]]]


 [[[0 0 4]
   [3 2 4]
   [2 2 2]]

  [[0 4 2]
   [2 4 2]
   [2 2 3]]

  [[4 2 0]
   [4 2 3]
   [2 3 0]]

  [[2 0 4]
   [2 3 4]
   [3 0 1]]

  [[0 4 3]
   [3 4 4]
   [0 1 4]]

  [[4 3 4]
   [4 4 1]
   [1 4 2]]

  [[3 4 4]
   [4 1 0]
   [4 2 0]]

  [[4 4 2]
   [1 0 0]
   [2 0 1]]]


 [[[3 2 4]
   [2 2 2]
   [4 0 3]]

  [[2 4 2]
   [2 2 3]
   [0 3 4]]

  [[4 2 3]
   [2 3 0]
   [3 4 4]]

  [[2 3 4]
   [3 0 1]
   [4 4 1]]

  [[3 4 4]
   [0 1 4]
   [4 1 2]]

  [[4 4 1]
   [1 4 2]
   [1 2 3]]

  [[4 1 0]
   [4 2 0]
   [2 3 2]]

  [[1 0 0]
   [2 0 1]
   [3 2 4]]]


 [[[2 2 2]
   [4 0 3]
   [3 3 3]]

  [[2 2 3]
   [0 3 4]
   [3 3 3]]

  [[2 3 0]
   [3 4 4]
   [3 3 1]]

  [[3 0 1]
   [4 4 1]
   [3 1 2]]

  [[0 1 4]
   [4 1 2]
   [1 2 2]]

  [[1 4 2]
   [1 2 3]
   [2 2 1]]

  [[4 2 0]
   [2 3 2]
   [2 1 0]]

  [[2 0 1]
   [3 2 4]
   [1 0 2]]]]


说明:参考前面说明过的stride_tricks.as_strided()函数。

85.Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★)
​创建一个满足 Z[i,j] == Z[j,i]的子类

代码如下:

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)

输出结果如下:

[[ 8  7  7  9  2]
 [ 7  6  9  9  8]
 [ 7  9  4 42 10]
 [ 9  9 42  6  1]
 [ 2  8 10  1  3]]

Process finished with exit code 0


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? (result has shape (n,1)) (★★★)
​考虑p个 nxn 矩阵和一组形状为(n,1)的向量,如何直接计算p个矩阵的乘积(n,1)

代码如下:

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)


输出结果如下:

[[200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]
 [200.]]

说明:我们看个简单例子,说明一下函数np.tensordot()
代码如下:

np.random.seed(10)
A = np.random.randint(0, 9, (3, 4, 5))
B = np.random.randint(0, 9, (4, 5, 2))
print(np.tensordot(A, B, [(1, 2), (0, 1)]))

解释:

  • (1,2) 是对A而言,不是取第1,2轴,而是除去1,2 轴,所以要取的是第0轴
  • (0,1) 是对B而言,不是取第0,1轴,而是除去0,1 轴,所以要取的是第2轴
  • A的形状是(3,4,5),第0轴上有3个元素,取法上面讲了;B的形状(4,5,2),第2轴上有2个元素,所以结果形状是(3,2).
  • Tensordot 的作用就是把取出的子数组做点乘操作,即是 np.sum(a*b) 操作。

拓展:numpy的叉乘与点乘。
dot函数:

  • 对于秩为1的数组,执行对应位置相乘,然后再相加,等价于向量的点乘;
  • 对于秩不为1的二维数组,执行矩阵乘法运算,等价于矩阵的叉乘;

multiply函数:

  • 数组和矩阵对应位置相乘,输出与相乘数组/矩阵的大小一致,效果上与运算符*对数组效果一样。

运算符 * 号

  • 对数组执行对应位置相乘,等价于multiply函数;
  • 对矩阵执行矩阵乘法运算,等价于dot函数;

具体可参考这个博客:https://blog.csdn.net/wzyaiwl/article/details/106310705

87 Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★)
​对于一个16x16的数组,如何得到一个区域(block-sum)的和(区域大小为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.]]

说明:

print("reduceat",np.add.reduceat(a,[1,3,2,4])) # >> reduceat [3 3 5 4]
 #第一步用到索引值列表中的13,对数组中索引值在13之间的元素进行reduce操作 得到3; 
 #第二步用到索引值32。由于23小,所以直接返回索引值为3的元素 得到3;
 #第三步用到索引值24。对索引值在24之间的数组元素进行reduce操作 得到4;
 #第四步用到索引值4。对索引值从7开始直到数组末端的元素进行reduce操作 得到5;

再看一个例子:
规则如下:如果indice中某元素小于其后元素,则相应结果为对以这两个元素为位置产生的slice里的数组元素进行reduce;否则结果是这个元素对应的数组元素。对于最后一个元素,因为其后再没元素,结果为对所有元素进行reduce。reduce和sum作用一样。例子:np.add.reduceat(np.array([1,2,3,4]),indices=[0,1,0,2,0,3,0]),返回array([1,2,3,3,6,4,10])

88.How to implement the Game of Life using numpy arrays? (★★★)
​如何利用numpy数组实现Game of Life

代码如下:

# 1. 每个细胞的状态由该细胞及周围八个细胞上一次的状态所决定;
# 2. 如果一个细胞周围有3个细胞为生,则该细胞为生,即该细胞若原先为死,则转为生,若原先为生,则保持不变;
# 3. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
# 4. 在其它情况下,该细胞为死,即该细胞若原先为生,则转为死,若原先为死,则保持不变
#
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)
    survive = ((N == 2) | (N == 3))
    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)

输出结果如下:

[[0 0 0 ... 0 0 0]
 [0 1 0 ... 1 1 0]
 [0 1 0 ... 0 1 0]
 ...
 [0 0 0 ... 1 1 0]
 [0 1 1 ... 1 1 0]
 [0 0 0 ... 0 0 0]]

Process finished with exit code 0


89.How to get the n largest values of an array (★★★)
​如何找到一个数组的n个最大值

代码如下:

Z = np.arange(10000)
np.random.shuffle(Z)
n = 5
print(Z[np.argsort(Z)[-n:]])   # slow
print (Z[np.argpartition(-Z,n)[:n]])    # fast

输出结果如下:

代码如下:

[9995 9996 9997 9998 9999]
[9996 9995 9997 9999 9998]

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)

    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]]

Process finished with exit code 0


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)

输出结果如下:

[(b'Hello', 2.5, 3) (b'World', 3.6, 2)]

92 Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★)
​考虑一个大向量Z, 用三种不同的方法计算它的立方

代码如下:

Z = np.random.choice(100, 10000)
print(Z)
print(np.power(Z,3))
print(Z**3)   # 方法一
print(Z*Z*Z)       # 方法二
print(np.einsum('i,i,i->i', Z, Z, Z))   # 方法三

输出结果如下:

[53 85 85 ... 86 70 41]
[148877 614125 614125 ... 636056 343000  68921]
[148877 614125 614125 ... 636056 343000  68921]
[148877 614125 614125 ... 636056 343000  68921]
[148877 614125 614125 ... 636056 343000  68921]

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? (★★★)
​考虑两个形状分别为(8,3) 和(2,2)的数组A和B. 如何在数组A中找到满足包含B中元素的行?(不考虑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)


输出结果如下:

[0 3 4 5]

94 Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★)
​考虑一个10x3的矩阵,分解出有不全相同值的行 (如 [2,2,3])。或者说从一个10x3的数组中去除一行元素完全相同的行

代码如下:

Z = np.random.randint(0, 5, (10, 3))
print(Z)

E = np.all(Z[:, 1:] == Z[:, :-1], axis=1)
U = Z[~E]
print(U)

方法2U = Z[Z.max(axis=1) != Z.min(axis=1), :]
print(U)

输出结果如下:

[[2 2 0]
 [3 4 0]
 [1 3 2]
 [3 1 1]
 [4 3 2]
 [3 2 0]
 [2 2 4]
 [2 1 4]
 [2 0 3]
 [4 4 2]]
____________
[[2 2 0]
 [3 4 0]
 [1 3 2]
 [3 1 1]
 [4 3 2]
 [3 2 0]
 [2 2 4]
 [2 1 4]
 [2 0 3]
 [4 4 2]]

Process finished with exit code 0


95.Convert a vector of ints into a matrix binary representation (★★★)
​把一个8位整型的一维数组表示为二进制的矩阵

代码如下:

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])

# 方法2
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? (★★★)
​给定一个二维数组,如何提取出唯一的(unique)行

代码如下:

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)

# NumPy >= 1.13
uZ = np.unique(Z, axis=0)
print(uZ)

输出结果如下:

[[0 0 0]
 [0 0 1]
 [0 1 1]
 [1 0 0]
 [1 1 0]]

97 Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★)
​考虑两个向量A和B,写出用einsum等式对应的inner, outer, sum, mul函数

代码如下:

A = np.random.uniform(0, 1, 10)
B = np.random.uniform(0, 1, 10)

print('sum')
print(np.einsum('i->', A))   # np.sum(A)

print('A*B')
print(np.einsum('i,i->i', A, B))   # A*B

print('inner')
print(np.einsum('i,i', A, B))   # np.inner(A, B)

print('outer')
print(np.einsum('i,j->ij', A, B))  # np.outer(A, B)

输出结果如下:

sum
4.994991703819576
A*B
[0.11917463 0.13661095 0.05406811 0.00613694 0.36325349 0.29081196
 0.34769536 0.33327491 0.29420788 0.66629835]
inner
2.6115325698708656
outer
[[0.11917463 0.12542189 0.02685579 0.04806351 0.31377784 0.36565551
  0.14324113 0.27423058 0.28003491 0.28824473]
 [0.12980637 0.13661095 0.02925164 0.05235132 0.3417704  0.39827614
  0.15601987 0.29869507 0.30501722 0.31395944]
 [0.23993135 0.25250881 0.05406811 0.09676507 0.6317212  0.73616523
  0.28838385 0.55210167 0.5637874  0.58031601]
 [0.0152167  0.01601437 0.00342906 0.00613694 0.04006441 0.04668836
  0.0182896  0.03501486 0.03575598 0.03680424]
 [0.13796577 0.14519808 0.03109034 0.05564203 0.36325349 0.42331108
  0.16582701 0.31747052 0.32419007 0.33369438]
 [0.09478158 0.09975013 0.02135886 0.03822571 0.24955278 0.29081196
  0.11392208 0.21810018 0.22271646 0.22924587]
 [0.2892777  0.30444194 0.06518822 0.11666661 0.76164643 0.88757132
  0.34769536 0.66565166 0.67974078 0.69966881]
 [0.14483401 0.15242636 0.03263809 0.05841202 0.38133705 0.44438445
  0.17408225 0.33327491 0.34032897 0.35030643]
 [0.12520623 0.13176967 0.028215   0.05049607 0.32965859 0.38416186
  0.15049077 0.28810978 0.29420788 0.30283321]
 [0.2754807  0.28992169 0.06207909 0.11110224 0.72531997 0.84523891
  0.33111215 0.63390364 0.64732078 0.66629835]]

Process finished with exit code 0


98.Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)?
​考虑一个由两个向量描述的路径(X,Y),如何用等距样例(equidistant samples)对其进行采样(sample)

代码如下:

phi = np.arange(0, 10*np.pi, 0.1)
a = 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. (★★★)
​给定整数n和一个二维数组X,从X中找出满足条件的行,指数为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)
# np.mod(X,1) 找出整数,
# axis =-1 表示最后一个维度
M &= (X.sum(axis=-1) == n)
# 在最后一个维度上和为4
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). (★★★)
采用自助法计算给定一维数组在95%置信区间上的算术平均值

代码如下:

X = np.random.randn(100)
N = 100
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.2152747   0.20287406]

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐