本文翻译整理自:https://github.com/rougier/numpy-100
文章目录
- 关于 100 个 NumPy 练习
- 相关链接资源
- 关键功能特性
- 100 个 NumPy 练习题
- 1、导入 NumPy 包并命名为 `np` (★☆☆)
- 2、打印 NumPy 版本和配置信息 (★☆☆)
- 3、创建一个大小为 10 的空向量 (★☆☆)
- 4、如何获取任意数组的内存大小? (★☆☆)
- 5、如何从命令行获取 NumPy add 函数的文档? (★☆☆)
- 6、创建一个大小为 10 的空向量,但第 5 个值为 1 (★☆☆)
- 7、创建一个值范围为 10 到 49 的向量 (★☆☆)
- 8、反转向量(第一个元素变为最后一个) (★☆☆)
- 9、创建一个 3x3 矩阵,值范围为 0 到 8 (★☆☆)
- 10、从 [1,2,0,0,4,0] 中找出非零元素的索引 (★☆☆)
- 11、创建一个 3x3 单位矩阵 (★☆☆)
- 12、创建一个 3x3x3 的随机值数组 (★☆☆)
- 13、创建一个 10x10 的随机值数组,并找出最小值和最大值 (★☆☆)
- 14、创建一个大小为 30 的随机向量,并计算其平均值 (★☆☆)
- 15、创建一个 2D 数组,边界为 1,内部为 0 (★☆☆)
- 16、如何为现有数组添加一个填充 0 的边框? (★☆☆)
- 17、以下表达式的结果是什么? (★☆☆)
- 18、创建一个 5x5 矩阵,对角线下方为 1,2,3,4 (★☆☆)
- 19、创建一个 8x8 矩阵并用棋盘图案填充 (★☆☆)
- 20、考虑一个形状为 (6,7,8) 的数组,第 100 个元素的 (x,y,z) 索引是什么? (★☆☆)
- 21、使用 tile 函数创建一个 8x8 棋盘矩阵 (★☆☆)
- 22、归一化一个 5x5 随机矩阵 (★☆☆)
- 23、创建一个自定义 dtype,将颜色描述为四个无符号字节 (RGBA) (★☆☆)
- 24、将 5x3 矩阵乘以 3x2 矩阵(实数矩阵乘积) (★☆☆)
- 25、给定一个一维数组,原地取反 3 到 8 之间的所有元素 (★☆☆)
- 26、以下脚本的输出是什么? (★☆☆)
- 27、考虑一个整数向量 Z,以下哪些表达式是合法的? (★☆☆)
- 28、以下表达式的结果是什么? (★☆☆)
- 29、如何将浮点数组远离零舍入? (★☆☆)
- 30、如何找到两个数组的共同值? (★☆☆)
- 31、如何忽略所有 NumPy 警告(不推荐)? (★☆☆)
- 32、以下表达式是否为真? (★☆☆)
- 33、如何获取昨天、今天和明天的日期? (★☆☆)
- 34、如何获取 2016 年 7 月的所有日期? (★★☆)
- 35、如何原地计算 ((A+B)*(-A/2))(不创建副本)? (★★☆)
- 36、使用 4 种不同方法提取正数随机数组的整数部分 (★★☆)
- 37、创建一个 5x5 矩阵,行值范围为 0 到 4 (★★☆)
- 38、考虑一个生成 10 个整数的生成器函数,并用它构建一个数组 (★☆☆)
- 39、创建一个大小为 10 的向量,值范围为 0 到 1(均不包含) (★★☆)
- 40、创建一个大小为 10 的随机向量并排序 (★★☆)
- 41、如何比 np.sum 更快地对小数组求和? (★★☆)
- 42、考虑两个随机数组 A 和 B,检查它们是否相等 (★★☆)
- 43、使数组不可变(只读) (★★☆)
- 44、考虑一个表示笛卡尔坐标的随机 10x2 矩阵,将其转换为极坐标 (★★☆)
- 45、创建一个大小为 10 的随机向量,并将最大值替换为 0 (★★☆)
- 46、创建一个结构化数组,`x` 和 `y` 坐标覆盖 [0,1]x[0,1] 区域 (★★☆)
- 47、给定两个数组 X 和 Y,构造柯西矩阵 C (Cij =1/(xi - yj)) (★★☆)
- 48、打印每种 NumPy 标量类型的最小和最大可表示值 (★★☆)
- 49、如何打印数组的所有值? (★★☆)
- 50、如何在向量中找到最接近给定标量的值? (★★☆)
- 51、创建一个表示位置 (x,y) 和颜色 (r,g,b) 的结构化数组 (★★☆)
- 52、考虑一个表示坐标的形状为 (100,2) 的随机向量,计算点与点之间的距离 (★★☆)
- 53、如何将浮点(32 位)数组原地转换为整数(32 位)数组?
- 54、如何读取以下文件? (★★☆)
- 55、numpy数组的枚举等效操作是什么? (★★☆)
- 56、生成通用的二维高斯分布数组 (★★☆)
- 57、如何在二维数组中随机放置p个元素? (★★☆)
- 58、减去矩阵每行的均值 (★★☆)
- 59、如何按第n列对数组排序? (★★☆)
- 60、如何判断给定的二维数组是否存在空列? (★★☆)
- 61、在数组中查找与给定值最接近的值 (★★☆)
- 62、考虑形状为(1,3)和(3,1)的两个数组,如何使用迭代器计算它们的和? (★★☆)
- 63、创建具有name属性的数组类 (★★☆)
- 64、给定一个向量,如何对第二个向量索引的元素加1(注意重复索引)? (★★★)
- 65、如何根据索引列表(I)将向量(X)的元素累加到数组(F)中? (★★★)
- 66、考虑形状为(w,h,3)的(dtype=ubyte)图像,如何计算唯一颜色数量? (★★☆)
- 67、考虑四维数组,如何一次性获取最后两个轴的和? (★★★)
- 68、考虑一维向量D,如何使用相同大小的子集索引向量S计算D子集的均值? (★★★)
- 69、如何获取点积的对角线? (★★★)
- 70、考虑向量[1,2,3,4,5],如何构建新向量并在每个值之间插入3个连续的零? (★★★)
- 71、考虑形状为(5,5,3)的数组,如何乘以形状为(5,5)的数组? (★★★)
- 72、如何交换数组的两行? (★★★)
- 73、考虑描述10个三角形(共享顶点)的10个三元组,如何找到组成所有三角形的唯一线段集合? (★★★)
- 74、给定对应于bincount的排序数组C,如何生成数组A使得np.bincount(A) == C? (★★★)
- 75、如何使用滑动窗口计算数组的平均值? (★★★)
- 76、考虑一维数组Z,构建二维数组,其第一行为(Z[0],Z[1],Z[2]),后续每行移动1位(最后一行应为(Z[-3],Z[-2],Z[-1])) (★★★)
- 77、如何原地取反布尔值或改变浮点数的符号? (★★★)
- 78、考虑描述线段的2组点P0,P1和点p,如何计算p到每条线段i (P0[i],P1[i])的距离? (★★★)
- 79、考虑描述线段的2组点P0,P1和点集P,如何计算每个点j (P[j])到每条线段i (P0[i],P1[i])的距离? (★★★)
- 80、如何从任意数组中提取以给定元素为中心、固定形状的子部分(必要时用`fill`值填充)? (★★★)
- 81、如何从数组 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]]?(★★★)
- 82、计算矩阵的秩(★★★)
- 83、如何找到数组中出现频率最高的值?
- 84、从随机 10x10 矩阵中提取所有连续的 3x3 块(★★★)
- 85、创建一个 2D 数组子类,使得 Z[i,j] == Z[j,i](★★★)
- 86、给定一组形状为 (n,n) 的 p 个矩阵和一组形状为 (n,1) 的 p 个向量,如何一次性计算 p 个矩阵乘积的和?(结果形状为 (n,1))(★★★)
- 87、给定一个 16x16 数组,如何计算 4x4 块的和?(★★★)
- 88、如何使用 NumPy 数组实现生命游戏?(★★★)
- 89、如何获取数组中最大的 n 个值?(★★★)
- 90、给定任意数量的向量,构建笛卡尔积(每个项目的所有组合)(★★★)
- 91、如何从常规数组创建记录数组?(★★★)
- 92、给定一个大向量 Z,用 3 种不同方法计算 Z 的 3 次方(★★★)
- 93、给定形状为 (8,3) 和 (2,2) 的两个数组 A 和 B,如何找到 A 中包含 B 每行元素的行(不考虑 B 中元素的顺序)?(★★★)
- 94、给定一个 10x3 矩阵,提取具有不等值的行(例如 [2,2,3])(★★★)
- 95、将整数向量转换为矩阵的二进制表示(★★★)
- 96、给定一个二维数组,如何提取唯一的行?(★★★)
- 97、给定两个向量 A 和 B,写出 inner、outer、sum 和 mul 函数的 einsum 等价形式(★★★)
- 98、给定由两个向量 (X,Y) 描述的路径,如何用等距样本对其进行采样?(★★★)
- 99、给定整数 n 和 2D 数组 X,从 X 中选择可以解释为具有 n 自由度的多项分布的行的行,即仅包含整数且总和为 n 的行。(★★★)
- 100、计算一维数组 X 均值的自助法 95% 置信区间(即对数组元素进行 N 次有放回重采样,计算每个样本的均值,然后计算均值的百分位数)。(★★★)
关于 100 个 NumPy 练习
本练习集收录了来自 NumPy 邮件列表、Stack Overflow 和 NumPy 官方文档的练习题。作者还自行创建了部分题目以达到 100 题的规模。该合集旨在为新老用户提供快速参考,同时也为教学者提供习题资源。如需扩展练习,建议阅读《从 Python 到 NumPy》。
→ 在 Binder 上测试:http://mybinder.org:/repo/rougier/numpy-100/notebooks/100_Numpy_exercises.ipynb
→ 在 GitHub 上阅读:<100_Numpy_exercises.md>
Julia:100 个 Julia 练习
注:Markdown 和 IPython Notebook 文件是通过程序从 source/exercises.ktx
中的源数据自动生成的。如需修改这些文件的内容,请先更改源文件中的文本,然后运行 generators.py
模块(需先安装 requirements.txt
中列出的库)。
键值文本格式(ktx
)是一种极简的人类可读格式,用于通过键值对存储文本(如 Markdown 等)。
相关链接资源
- GitHub:https://github.com/rougier/numpy-100
- Binder 测试环境:http://mybinder.org:/repo/rougier/numpy-100/notebooks/100_Numpy_exercises.ipynb
- 配套教材《从 Python 到 NumPy》:http://www.labri.fr/perso/nrougier/from-python-to-numpy/
- DOI 标识:https://zenodo.org/badge/latestdoi/10173/rougier/numpy-100
- License:MIT
关键功能特性
1、精选 100 个 NumPy 实战练习题
2、涵盖邮件列表、Stack Overflow 和官方文档的经典问题
3、提供教学场景适用的习题资源
4、支持通过 Binder 在线测试
100 个 NumPy 练习题
这是从 NumPy 邮件列表、Stack Overflow 和 NumPy 文档中收集的一系列练习题。本合集旨在为新老用户提供快速参考,同时也为教学者提供练习素材。
如果发现错误或有更好的解决方案,欢迎在 https://github.com/rougier/numpy-100 提交 issue。文件自动生成,请参阅文档以编程方式更新问题/答案/提示。
1、导入 NumPy 包并命名为 np
(★☆☆)
提示:import … as
import numpy as np
2、打印 NumPy 版本和配置信息 (★☆☆)
提示:np.__version__, np.show_config)
print(np.__version__)
np.show_config()
3、创建一个大小为 10 的空向量 (★☆☆)
提示:np.zeros
Z = np.zeros(10)
print(Z)
4、如何获取任意数组的内存大小? (★☆☆)
提示:size, itemsize
Z = np.zeros((10,10))
print("%d bytes" % (Z.size * Z.itemsize))
5、如何从命令行获取 NumPy add 函数的文档? (★☆☆)
提示:np.info
%run `python -c "import numpy; numpy.info(numpy.add)"`
6、创建一个大小为 10 的空向量,但第 5 个值为 1 (★☆☆)
提示:array[4]
Z = np.zeros(10)
Z[4] = 1
print(Z)
7、创建一个值范围为 10 到 49 的向量 (★☆☆)
提示:arange
Z = np.arange(10,50)
print(Z)
8、反转向量(第一个元素变为最后一个) (★☆☆)
提示:array[::-1]
Z = np.arange(50)
Z = Z[::-1]
print(Z)
9、创建一个 3x3 矩阵,值范围为 0 到 8 (★☆☆)
提示:reshape
Z = np.arange(9).reshape(3, 3)
print(Z)
10、从 [1,2,0,0,4,0] 中找出非零元素的索引 (★☆☆)
提示:np.nonzero
nz = np.nonzero([1,2,0,0,4,0])
print(nz)
11、创建一个 3x3 单位矩阵 (★☆☆)
提示:np.eye
Z = np.eye(3)
print(Z)
12、创建一个 3x3x3 的随机值数组 (★☆☆)
提示:np.random.random
Z = np.random.random((3,3,3))
print(Z)
13、创建一个 10x10 的随机值数组,并找出最小值和最大值 (★☆☆)
提示:min, max
Z = np.random.random((10,10))
Zmin, Zmax = Z.min(), Z.max()
print(Zmin, Zmax)
14、创建一个大小为 30 的随机向量,并计算其平均值 (★☆☆)
提示:mean
Z = np.random.random(30)
m = Z.mean()
print(m)
15、创建一个 2D 数组,边界为 1,内部为 0 (★☆☆)
提示:array[1:-1, 1:-1]
Z = np.ones((10,10))
Z[1:-1,1:-1] = 0
print(Z)
16、如何为现有数组添加一个填充 0 的边框? (★☆☆)
提示:np.pad
Z = np.ones((5,5))
Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
print(Z)# 使用花式索引
Z[:, [0, -1]] = 0
Z[[0, -1], :] = 0
print(Z)
17、以下表达式的结果是什么? (★☆☆)
0 * np.nan
np.nan == np.nan
np.inf > np.nan
np.nan - np.nan
np.nan in set([np.nan])
0.3 == 3 * 0.1
提示:NaN = 非数字, inf = 无穷大
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)
18、创建一个 5x5 矩阵,对角线下方为 1,2,3,4 (★☆☆)
提示:np.diag
Z = np.diag(1+np.arange(4),k=-1)
print(Z)
19、创建一个 8x8 矩阵并用棋盘图案填充 (★☆☆)
提示:array[::2]
Z = np.zeros((8,8),dtype=int)
Z[1::2,::2] = 1
Z[::2,1::2] = 1
print(Z)
20、考虑一个形状为 (6,7,8) 的数组,第 100 个元素的 (x,y,z) 索引是什么? (★☆☆)
提示:np.unravel_index
print(np.unravel_index(99,(6,7,8)))
21、使用 tile 函数创建一个 8x8 棋盘矩阵 (★☆☆)
提示:np.tile
Z = np.tile( np.array([[0,1],[1,0]]), (4,4))
print(Z)
22、归一化一个 5x5 随机矩阵 (★☆☆)
提示:(x -mean)/std
Z = np.random.random((5,5))
Z = (Z - np.mean (Z)) / (np.std (Z))
print(Z)
23、创建一个自定义 dtype,将颜色描述为四个无符号字节 (RGBA) (★☆☆)
提示:np.dtype
color = np.dtype([("r", np.ubyte), ("g", np.ubyte), ("b", np.ubyte), ("a", np.ubyte)])
24、将 5x3 矩阵乘以 3x2 矩阵(实数矩阵乘积) (★☆☆)
提示:
Z = np.matmul(np.ones((5, 3)), np.ones((3, 2)))
print(Z)# Python 3.5 及更高版本的替代方案
Z = np.ones((5,3)) @ np.ones((3,2))
print(Z)
25、给定一个一维数组,原地取反 3 到 8 之间的所有元素 (★☆☆)
提示:>, <
# 作者:Evgeni BurovskiZ = np.arange(11)
Z[(3 < Z) & (Z < 8)] *= -1
print(Z)
26、以下脚本的输出是什么? (★☆☆)
# 作者:Jake VanderPlasprint(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))
提示:np.sum
# 作者:Jake VanderPlasprint(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))
27、考虑一个整数向量 Z,以下哪些表达式是合法的? (★☆☆)
Z**Z
2 << Z >> 2
Z <- Z
1j*Z
Z/1/1
Z<Z>Z
无提示...
Z**Z
2 << Z >> 2
Z <- Z
1j*Z
Z/1/1
Z<Z>Z
28、以下表达式的结果是什么? (★☆☆)
np.array(0) / np.array(0)
np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float)
无提示...
print(np.array(0) / np.array(0))
print(np.array(0) // np.array(0))
print(np.array([np.nan]).astype(int).astype(float))
29、如何将浮点数组远离零舍入? (★☆☆)
提示:np.uniform, np.copysign, np.ceil, np.abs, np.where
# 作者:Charles R HarrisZ = np.random.uniform(-10,+10,10)
print(np.copysign(np.ceil(np.abs(Z)), Z))# 更易读但效率较低
print(np.where(Z>0, np.ceil(Z), np.floor(Z)))
30、如何找到两个数组的共同值? (★☆☆)
提示:np.intersect1d
Z1 = np.random.randint(0,10,10)
Z2 = np.random.randint(0,10,10)
print(np.intersect1d(Z1,Z2))
31、如何忽略所有 NumPy 警告(不推荐)? (★☆☆)
提示:np.seterr, np.errstate
# 开启自杀模式
defaults = np.seterr(all="ignore")
Z = np.ones(1) / 0# 恢复理智
_ = np.seterr(**defaults)# 使用上下文管理器等效实现
with np.errstate(all="ignore"):np.arange(3) / 0
32、以下表达式是否为真? (★☆☆)
np.sqrt(-1) == np.emath.sqrt(-1)
提示:虚数
np.sqrt(-1) == np.emath.sqrt(-1)
33、如何获取昨天、今天和明天的日期? (★☆☆)
提示:np.datetime64, np.timedelta64
yesterday = np.datetime64('today') - np.timedelta64(1)
today = np.datetime64('today')
tomorrow = np.datetime64('today') + np.timedelta64(1)
34、如何获取 2016 年 7 月的所有日期? (★★☆)
提示:np.arange(dtype=datetime64['D'])
Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
print(Z)
35、如何原地计算 ((A+B)*(-A/2))(不创建副本)? (★★☆)
提示:np.add(out=), np.negative(out=), np.multiply(out=), np.divide(out=)
A = np.ones(3)*1
B = np.ones(3)*2
np.add(A,B,out=B)
np.divide(A,2,out=A)
np.negative(A,out=A)
np.multiply(A,B,out=A)
36、使用 4 种不同方法提取正数随机数组的整数部分 (★★☆)
提示:%, np.floor, astype, np.trunc
Z = np.random.uniform(0,10,10)print(Z - Z%1)
print(Z // 1)
print(np.floor(Z))
print(Z.astype(int))
print(np.trunc(Z))
37、创建一个 5x5 矩阵,行值范围为 0 到 4 (★★☆)
提示:np.arange
Z = np.zeros((5,5))
Z += np.arange(5)
print(Z)# 不使用广播
Z = np.tile(np.arange(0, 5), (5,1))
print(Z)
38、考虑一个生成 10 个整数的生成器函数,并用它构建一个数组 (★☆☆)
提示:np.fromiter
def generate():for x in range(10):yield x
Z = np.fromiter(generate(),dtype=float,count=-1)
print(Z)
39、创建一个大小为 10 的向量,值范围为 0 到 1(均不包含) (★★☆)
提示:np.linspace
Z = np.linspace(0,1,11,endpoint=False)[1:]
print(Z)
40、创建一个大小为 10 的随机向量并排序 (★★☆)
提示:sort
Z = np.random.random(10)
Z.sort()
print(Z)
41、如何比 np.sum 更快地对小数组求和? (★★☆)
提示:np.add.reduce
# 作者:Evgeni BurovskiZ = np.arange(10)
np.add.reduce(Z)
42、考虑两个随机数组 A 和 B,检查它们是否相等 (★★☆)
提示:np.allclose, np.array_equal
A = np.random.randint(0,2,5)
B = np.random.randint(0,2,5)# 假设数组形状相同且对值比较有容差
equal = np.allclose(A,B)
print(equal)# 检查形状和元素值是否完全相等(无容差)
equal = np.array_equal(A,B)
print(equal)
43、使数组不可变(只读) (★★☆)
提示:flags.writeable
Z = np.zeros(10)
Z.flags.writeable = False
Z[0] = 1
44、考虑一个表示笛卡尔坐标的随机 10x2 矩阵,将其转换为极坐标 (★★☆)
提示:np.sqrt, np.arctan2
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、创建一个大小为 10 的随机向量,并将最大值替换为 0 (★★☆)
提示:argmax
Z = np.random.random(10)
Z[Z.argmax()] = 0
print(Z)
46、创建一个结构化数组,x
和 y
坐标覆盖 [0,1]x[0,1] 区域 (★★☆)
提示:np.meshgrid
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)
47、给定两个数组 X 和 Y,构造柯西矩阵 C (Cij =1/(xi - yj)) (★★☆)
提示:np.subtract.outer
# 作者:Evgeni BurovskiX = np.arange(8)
Y = X + 0.5
C = 1.0 / np.subtract.outer(X, Y)
print(np.linalg.det(C))
48、打印每种 NumPy 标量类型的最小和最大可表示值 (★★☆)
提示:np.iinfo, np.finfo, eps
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)
49、如何打印数组的所有值? (★★☆)
提示:np.set_printoptions
np.set_printoptions(threshold=float("inf"))
Z = np.zeros((40,40))
print(Z)
50、如何在向量中找到最接近给定标量的值? (★★☆)
提示:argmin
Z = np.arange(100)
v = np.random.uniform(0,100)
index = (np.abs(Z-v)).argmin()
print(Z[index])
51、创建一个表示位置 (x,y) 和颜色 (r,g,b) 的结构化数组 (★★☆)
提示:dtype
Z = np.zeros(10, [ ('position', [ ('x', float, 1), ('y', float, 1)]), ('color', [ ('r', float, 1), ('g', float, 1), ('b', float, 1)])])
print(Z)
52、考虑一个表示坐标的形状为 (100,2) 的随机向量,计算点与点之间的距离 (★★☆)
提示:np.atleast_2d, T, np.sqrt
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)# 使用 scipy 更快
import scipy
# 感谢 Gavin Heverly-Coulson (#issue 1)
import scipy.spatialZ = np.random.random((10,2))
D = scipy.spatial.distance.cdist(Z,Z)
print(D)
53、如何将浮点(32 位)数组原地转换为整数(32 位)数组?
提示:view 和 [:] =
# 感谢 Vikas (https://stackoverflow.com/a/10622758/5989906)
# 和 unutbu (https://stackoverflow.com/a/4396247/5989906)
Z = (np.random.rand(10)*100).astype(np.float32)
Y = Z.view(np.int32)
Y[:] = Z
print(Y)
54、如何读取以下文件? (★★☆)
1, 2, 3, 4, 5
6, , , 7, 8, , 9,10,11
提示:np.genfromtxt
from io import StringIO# 模拟文件
s = StringIO('''1, 2, 3, 4, 56, , , 7, 8, , 9,10,11
''')
Z = np.genfromtxt(s, delimiter=",", dtype=np.int)
print(Z)
55、numpy数组的枚举等效操作是什么? (★★☆)
提示:np.ndenumerate, np.ndindex
Z = np.arange(9).reshape(3,3)
for index, value in np.ndenumerate(Z):print(index, value)
for index in np.ndindex(Z.shape):print(index, Z[index])
56、生成通用的二维高斯分布数组 (★★☆)
提示:np.meshgrid, np.exp
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)
57、如何在二维数组中随机放置p个元素? (★★☆)
提示:np.put, np.random.choice
# 作者:Divakarn = 10
p = 3
Z = np.zeros((n,n))
np.put(Z, np.random.choice(range(n*n), p, replace=False),1)
print(Z)
58、减去矩阵每行的均值 (★★☆)
提示:mean(axis=,keepdims=)
# 作者:Warren WeckesserX = np.random.rand(5, 10)# 新版numpy
Y = X - X.mean(axis=1, keepdims=True)# 旧版numpy
Y = X - X.mean(axis=1).reshape(-1, 1)print(Y)
59、如何按第n列对数组排序? (★★☆)
提示:argsort
# 作者:Steve TjoaZ = np.random.randint(0,10,(3,3))
print(Z)
print(Z[Z[:,1].argsort()])
60、如何判断给定的二维数组是否存在空列? (★★☆)
提示:any, ~
# 作者:Warren Weckesser# 空列定义为0
Z = np.random.randint(0,3,(3,10))
print((~Z.any(axis=0)).any())# 空列定义为np.nan
Z=np.array([[0,1,np.nan], [1,2,np.nan], [4,5,np.nan]
])
print(np.isnan(Z).all(axis=0))
61、在数组中查找与给定值最接近的值 (★★☆)
提示:np.abs, argmin, flat
Z = np.random.uniform(0,1,10)
z = 0.5
m = Z.flat[np.abs(Z - z).argmin()]
print(m)
62、考虑形状为(1,3)和(3,1)的两个数组,如何使用迭代器计算它们的和? (★★☆)
提示:np.nditer
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])
63、创建具有name属性的数组类 (★★☆)
提示:class方法
class NamedArray(np.ndarray):def __new__(cls, array, name="no name"):obj = np.asarray(array).view(cls)obj.name = namereturn objdef __array_finalize__(self, obj):if obj is None: returnself.name = getattr(obj, 'name', "no name")Z = NamedArray(np.arange(10), "range_10")
print (Z.name)
64、给定一个向量,如何对第二个向量索引的元素加1(注意重复索引)? (★★★)
提示:np.bincount | np.add.at
# 作者:Brett OlsenZ = np.ones(10)
I = np.random.randint(0,len(Z),20)
Z += np.bincount(I, minlength=len(Z))
print(Z)# 另一种解法
# 作者:Bartosz Telenczuk
np.add.at(Z, I, 1)
print(Z)
65、如何根据索引列表(I)将向量(X)的元素累加到数组(F)中? (★★★)
提示:np.bincount
# 作者:Alan G IsaacX = [1,2,3,4,5,6]
I = [1,3,9,3,4,1]
F = np.bincount(I,X)
print(F)
66、考虑形状为(w,h,3)的(dtype=ubyte)图像,如何计算唯一颜色数量? (★★☆)
提示:np.unique
# 作者:Fisher Wangw, h = 256, 256
I = np.random.randint(0, 4, (h, w, 3)).astype(np.ubyte)
colors = np.unique(I.reshape(-1, 3), axis=0)
n = len(colors)
print(n)# 更快的版本
# 作者:Mark Setchell
# https://stackoverflow.com/a/59671950/2836621w, h = 256, 256
I = np.random.randint(0,4,(h,w,3), dtype=np.uint8)# 将每个像素视为单个24位整数,而不是三个8位字节
I24 = np.dot(I.astype(np.uint32),[1,256,65536])# 计算唯一颜色数量
n = len(np.unique(I24))
print(n)
67、考虑四维数组,如何一次性获取最后两个轴的和? (★★★)
提示:sum(axis=(-2,-1))
A = np.random.randint(0,10,(3,4,3,4))
# 通过传递轴元组解法(numpy 1.7.0引入)
sum = A.sum(axis=(-2,-1))
print(sum)
# 通过展平最后两个维度解法
# (适用于不接受轴元组的函数)
sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1)
print(sum)
68、考虑一维向量D,如何使用相同大小的子集索引向量S计算D子集的均值? (★★★)
提示:np.bincount
# 作者:Jaime Fernández del RíoD = 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解法参考(代码更直观)
import pandas as pd
print(pd.Series(D).groupby(S).mean())
69、如何获取点积的对角线? (★★★)
提示:np.diag
# 作者:Mathieu BlondelA = np.random.uniform(0,1,(5,5))
B = np.random.uniform(0,1,(5,5))# 慢速版本
np.diag(np.dot(A, B))# 快速版本
np.sum(A * B.T, axis=1)# 更快的版本
np.einsum("ij,ji->i", A, B)
70、考虑向量[1,2,3,4,5],如何构建新向量并在每个值之间插入3个连续的零? (★★★)
提示:array[::4]
# 作者:Warren WeckesserZ = np.array([1,2,3,4,5])
nz = 3
Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz))
Z0[::nz+1] = Z
print(Z0)
71、考虑形状为(5,5,3)的数组,如何乘以形状为(5,5)的数组? (★★★)
提示:array[:, :, None]
A = np.ones((5,5,3))
B = 2*np.ones((5,5))
print(A * B[:,:,None])
72、如何交换数组的两行? (★★★)
提示:array[[]] = array[[]]
# 作者:Eelco HoogendoornA = np.arange(25).reshape(5,5)
A[[0,1]] = A[[1,0]]
print(A)
73、考虑描述10个三角形(共享顶点)的10个三元组,如何找到组成所有三角形的唯一线段集合? (★★★)
提示:repeat, np.roll, np.sort, view, np.unique
# 作者:Nicolas P. Rougierfaces = 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、给定对应于bincount的排序数组C,如何生成数组A使得np.bincount(A) == C? (★★★)
提示:np.repeat
# 作者:Jaime Fernández del RíoC = np.bincount([1,1,2,3,4,4,6])
A = np.repeat(np.arange(len(C)), C)
print(A)
75、如何使用滑动窗口计算数组的平均值? (★★★)
提示:np.cumsum, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)
# 作者:Jaime Fernández del Ríodef 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))# 作者:Jeff Luo (@Jeff1999)
# 确保NumPy >= 1.20.0from numpy.lib.stride_tricks import sliding_window_viewZ = np.arange(20)
print(sliding_window_view(Z, window_shape=3).mean(axis=-1))
76、考虑一维数组Z,构建二维数组,其第一行为(Z[0],Z[1],Z[2]),后续每行移动1位(最后一行应为(Z[-3],Z[-2],Z[-1])) (★★★)
提示:from numpy.lib import stride_tricks, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)
# 作者:Joe Kington / Erik Rigtorp
from numpy.lib import stride_tricksdef rolling(a, window):shape = (a.size - window + 1, window)strides = (a.strides[0], a.strides[0])return stride_tricks.as_strided(a, shape=shape, strides=strides)
Z = rolling(np.arange(10), 3)
print(Z)# 作者:Jeff Luo (@Jeff1999)Z = np.arange(10)
print(sliding_window_view(Z, window_shape=3))
77、如何原地取反布尔值或改变浮点数的符号? (★★★)
提示:np.logical_not, np.negative
# 作者:Nathaniel J. SmithZ = np.random.randint(0,2,100)
np.logical_not(Z, out=Z)Z = np.random.uniform(-1.0,1.0,100)
np.negative(Z, out=Z)
78、考虑描述线段的2组点P0,P1和点p,如何计算p到每条线段i (P0[i],P1[i])的距离? (★★★)
无提示...
def distance(P0, P1, p):T = P1 - P0L = (T**2).sum(axis=1)U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / LU = U.reshape(len(U),1)D = P0 + U*T - preturn 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、考虑描述线段的2组点P0,P1和点集P,如何计算每个点j (P[j])到每条线段i (P0[i],P1[i])的距离? (★★★)
无提示...
# 作者:Italmassov Kuanysh# 基于前一问题的distance函数
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]))# 作者:Yang Wu (广播)
def distance_points_to_lines(p: np.ndarray, p_1: np.ndarray, p_2: np.ndarray) -> np.ndarray:x_0, y_0 = p.T # 形状 -> (n points, )x_1, y_1 = p_1.T # 形状 -> (n lines, )x_2, y_2 = p_2.T # 形状 -> (n lines, )# 从p_1到p_2的位移向量坐标dx = x_2 - x_1 # 形状 -> (n lines, )dy = y_2 - y_1 # 形状 -> (n lines, )# '叉积'项cross_term = x_2 * y_1 - y_2 * x_1 # 形状 -> (n lines, )# 广播x_0, y_0 (n points, 1)和dx, dy, cross_term (1, n lines) -> (n points, n lines)numerator = np.abs(dy[np.newaxis, :] * x_0[:, np.newaxis]- dx[np.newaxis, :] * y_0[:, np.newaxis]+ cross_term[np.newaxis, :])denominator = np.sqrt(dx**2 + dy**2) # 形状 -> (n lines, )# 形状 (n points, n lines) / (1, n_lines) -> (n points, n lines)return numerator / denominator[np.newaxis, :]distance_points_to_lines(p, P0, P1)
80、如何从任意数组中提取以给定元素为中心、固定形状的子部分(必要时用fill
值填充)? (★★★)
提示:minimum maximum
# 作者:Nicolas RougierZ = 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%2R_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)
81、如何从数组 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]]?(★★★)
提示:stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)
# 作者:Stefan van der WaltZ = np.arange(1,15,dtype=np.uint32)
R = stride_tricks.as_strided(Z,(11,4),(4,4))
print(R)# 作者:Jeff Luo (@Jeff1999)Z = np.arange(1, 15, dtype=np.uint32)
print(sliding_window_view(Z, window_shape=4))
82、计算矩阵的秩(★★★)
提示:np.linalg.svd, np.linalg.matrix_rank
# 作者:Stefan van der WaltZ = np.random.uniform(0,1,(10,10))
U, S, V = np.linalg.svd(Z) # 奇异值分解
rank = np.sum(S > 1e-10)
print(rank)# 替代方案:
# 作者:Jeff Luo (@Jeff1999)rank = np.linalg.matrix_rank(Z)
print(rank)
83、如何找到数组中出现频率最高的值?
提示:np.bincount, argmax
Z = np.random.randint(0,10,50)
print(np.bincount(Z).argmax())
84、从随机 10x10 矩阵中提取所有连续的 3x3 块(★★★)
提示:stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)
# 作者:Chris BarkerZ = 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)# 作者:Jeff Luo (@Jeff1999)Z = np.random.randint(0,5,(10,10))
print(sliding_window_view(Z, window_shape=(3, 3)))
85、创建一个 2D 数组子类,使得 Z[i,j] == Z[j,i](★★★)
提示:类方法
# 作者:Eric O. Lebigot
# 注意:仅适用于 2D 数组和通过索引设置值class Symetric(np.ndarray):def __setitem__(self, index, value):i,j = indexsuper(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、给定一组形状为 (n,n) 的 p 个矩阵和一组形状为 (n,1) 的 p 个向量,如何一次性计算 p 个矩阵乘积的和?(结果形状为 (n,1))(★★★)
提示:np.tensordot
# 作者:Stefan van der Waltp, 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)# 原理说明:
# M 的形状是 (p,n,n)
# V 的形状是 (p,n,1)
# 因此,对 M 和 V 的配对轴 0 和 0(独立地)、2 和 1 求和,
# 最终得到形状为 (n,1) 的向量。
87、给定一个 16x16 数组,如何计算 4x4 块的和?(★★★)
提示:np.add.reduceat, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)
# 作者:Robert KernZ = 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)# 替代方案:
# 作者:Sebastian Wallkötter (@FirefoxMetzger)Z = np.ones((16,16))
k = 4windows = np.lib.stride_tricks.sliding_window_view(Z, (k, k))
S = windows[::k, ::k, ...].sum(axis=(-2, -1))# 作者:Jeff Luo (@Jeff1999)Z = np.ones((16, 16))
k = 4
print(sliding_window_view(Z, window_shape=(k, k))[::k, ::k].sum(axis=(-2, -1)))
88、如何使用 NumPy 数组实现生命游戏?(★★★)
无提示...
# 作者:Nicolas Rougierdef iterate(Z):# 计算邻居数量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:])# 应用规则birth = (N==3) & (Z[1:-1,1:-1]==0)survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1)Z[...] = 0Z[1:-1,1:-1][birth | survive] = 1return ZZ = np.random.randint(0,2,(50,50))
for i in range(100): Z = iterate(Z)
print(Z)
89、如何获取数组中最大的 n 个值?(★★★)
提示:np.argsort | np.argpartition
Z = np.arange(10000)
np.random.shuffle(Z)
n = 5# 慢速方法
print (Z[np.argsort(Z)[-n:]])# 快速方法
print (Z[np.argpartition(-Z,n)[:n]])
90、给定任意数量的向量,构建笛卡尔积(每个项目的所有组合)(★★★)
提示:np.indices
# 作者:Stefan Van der Waltdef 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).Tfor n, arr in enumerate(arrays):ix[:, n] = arrays[n][ix[:, n]]return ixprint (cartesian(([1, 2, 3], [4, 5], [6, 7])))
91、如何从常规数组创建记录数组?(★★★)
提示:np.core.records.fromarrays
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)
92、给定一个大向量 Z,用 3 种不同方法计算 Z 的 3 次方(★★★)
提示:np.power, *, np.einsum
# 作者:Ryan G.x = np.random.rand(int(5e7))%timeit np.power(x,3)
%timeit x*x*x
%timeit np.einsum('i,i,i->i',x,x,x)
93、给定形状为 (8,3) 和 (2,2) 的两个数组 A 和 B,如何找到 A 中包含 B 每行元素的行(不考虑 B 中元素的顺序)?(★★★)
提示:np.where
# 作者:Gabe SchwartzA = 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、给定一个 10x3 矩阵,提取具有不等值的行(例如 [2,2,3])(★★★)
无提示...
# 作者:Robert KernZ = np.random.randint(0,5,(10,3))
print(Z)
# 适用于所有数据类型(包括字符串数组和记录数组)的解决方案
E = np.all(Z[:,1:] == Z[:,:-1], axis=1)
U = Z[~E]
print(U)
# 仅适用于数值数组的解决方案,适用于任意列数的 Z
U = Z[Z.max(axis=1) != Z.min(axis=1),:]
print(U)
95、将整数向量转换为矩阵的二进制表示(★★★)
提示:np.unpackbits
# 作者:Warren WeckesserI = 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])# 作者:Daniel T. McDonaldI = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8)
print(np.unpackbits(I[:, np.newaxis], axis=1))
96、给定一个二维数组,如何提取唯一的行?(★★★)
提示:np.ascontiguousarray | np.unique
# 作者:Jaime Fernández del RíoZ = 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)# 作者:Andreas Kouzelis
# NumPy >= 1.13
uZ = np.unique(Z, axis=0)
print(uZ)
97、给定两个向量 A 和 B,写出 inner、outer、sum 和 mul 函数的 einsum 等价形式(★★★)
提示:np.einsum
# 作者:Alex Riley
# 建议阅读:http://ajcr.net/Basic-guide-to-einsum/A = np.random.uniform(0,1,10)
B = np.random.uniform(0,1,10)np.einsum('i->', A) # np.sum(A)
np.einsum('i,i->i', A, B) # A * B
np.einsum('i,i', A, B) # np.inner(A, B)
np.einsum('i,j->ij', A, B) # np.outer(A, B)
98、给定由两个向量 (X,Y) 描述的路径,如何用等距样本对其进行采样?(★★★)
提示:np.cumsum, np.interp
# 作者:Bas Swinckelsphi = 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、给定整数 n 和 2D 数组 X,从 X 中选择可以解释为具有 n 自由度的多项分布的行的行,即仅包含整数且总和为 n 的行。(★★★)
提示:np.logical_and.reduce, np.mod
# 作者:Evgeni BurovskiX = 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])
100、计算一维数组 X 均值的自助法 95% 置信区间(即对数组元素进行 N 次有放回重采样,计算每个样本的均值,然后计算均值的百分位数)。(★★★)
提示:np.percentile
# 作者:Jessica B. HamrickX = np.random.randn(100) # 随机一维数组
N = 1000 # 自助法样本数量
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)
伊织 xAI 2025-04-25(五)