Numpy100练习前50道解析
# 1. 打印numpy版本和配置
print(np.__version__)
np.show_config()
# 知识点:打印Numpy版本和配置
# 解析:使用`np.__version__`打印Numpy的版本,`np.show_config()`打印Numpy的配置信息。
# 2. 创建一个大小为10的空向量
Z = np.zeros(10)
print(Z)
# 知识点:创建空向量
# 解析:使用`np.zeros(10)`创建一个包含10个元素的空向量,所有元素初始化为0。
# 3. 如何查询任何数组的存储大小
Z = np.zeros((10, 10))
print("%d bytes" % (Z.size * Z.itemsize))
# 知识点:数组存储大小
# 解析:`Z.size`获取数组的元素数量,`Z.itemsize`获取每个元素的大小(字节),相乘得到数组的总存储大小。
# 4. 如何通过命令行得到numpy相加(add)函数的文档
# 可以使用命令行工具:`python -c "import numpy; numpy.info(numpy.add)"`
# 知识点:命令行获取函数文档
# 解析:在命令行中执行此命令,可以查看`numpy.add`函数的详细文档。
# 5. 创建一个大小为10的空向量,但是第五个元素值为1
Z = np.zeros(10)
Z[4] = 1
print(Z)
# 知识点:索引赋值
# 解析:创建一个大小为10的空向量,并将索引为4的元素(即第五个元素)赋值为1。
# 6. 创建一个值在[10, 49]的向量
Z = np.arange(10, 50)
print(Z)
# 知识点:创建范围向量
# 解析:使用`np.arange(10, 50)`创建一个从10到49的整数向量。
# 7. 反转一个向量(第一个元素变为最后一个)
Z = np.arange(50)
Z = Z[::-1]
print(Z)
# 知识点:反转向量
# 解析:使用切片操作`[::-1]`反转向量,将第一个元素变为最后一个。
# 8. 创建一个值从0到8的3x3矩阵
Z = np.arange(9).reshape(3, 3)
print(Z)
# 知识点:矩阵重塑
# 解析:使用`np.arange(9)`创建一个包含0到8的向量,然后使用`reshape(3, 3)`将其重塑为3x3矩阵。
# 9. 从[1,2,0,0,4,0]找出非零元素索引
nz = np.nonzero([1, 2, 0, 0, 4, 0])
print(nz)
# 知识点:查找非零元素索引
# 解析:使用`np.nonzero`函数找到数组中所有非零元素的索引。
# 10. 创建一个3x3的单位矩阵
Z = np.eye(3)
print(Z)
# 知识点:单位矩阵
# 解析:使用`np.eye(3)`创建一个3x3的单位矩阵,即对角线元素为1,其他元素为0。
# 11. 创建一个3x3x3的随机数数组
Z = np.random.random((3, 3, 3))
print(Z)
# 知识点:随机数组
# 解析:使用`np.random.random((3, 3, 3))`创建一个3x3x3的随机数组,每个元素都是0到1之间的随机浮点数。
# 12. 创建一个10x10的随机数数组并找到最小值和最大值
Z = np.random.random((10, 10))
Zmin, Zmax = Z.min(), Z.max()
print(Zmin, Zmax)
# 知识点:最小值和最大值
# 解析:使用`np.random.random((10, 10))`创建一个10x10的随机数组,然后使用`min()`和`max()`方法找到最小值和最大值。
# 13. 创建一个大小为30的随机向量并找到平均值
Z = np.random.random(30)
m = Z.mean()
print(m)
# 知识点:平均值
# 解析:使用`np.random.random(30)`创建一个包含30个元素的随机向量,然后使用`mean()`方法计算其平均值。
# 14. 创建一个边缘全为1、内部全为0的二维数组
Z = np.ones((10, 10))
Z[1:-1, 1:-1] = 0
print(Z)
# 知识点:二维数组边界处理
# 解析:使用`np.ones((10, 10))`创建一个10x10的全1数组,然后将内部区域(即索引1到-2)设置为0。
# 15. 如何在一个现有数组外加上一个为0的包围圈
Z = np.ones((5, 5))
Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
print(Z)
# 知识点:数组填充
# 解析:使用`np.pad`函数在数组外部添加一个宽度为1的0值包围圈。
# 16. 下列表达式的结果是什么
print(0 * np.nan) # nan
print(np.nan == np.nan) # False
print(np.inf > np.nan) # False
print(np.nan in set([np.nan])) # True
print(0.3 == 3 * 0.1) # False
# 知识点:特殊值处理
# 解析:这些表达式涉及到NaN(Not a Number)和浮点数精度问题。NaN与任何数值(包括自身)比较都为False。
# 17. 创建一个5x5的矩阵,其对角线下方为1,2,3,4
Z = np.diag(1 + np.arange(4), k=-1)
print(Z)
# 知识点:对角矩阵
# 解析:使用`np.diag`函数创建一个对角矩阵,其中`k=-1`表示对角线位于主对角线的下方。
# 18. 创建一个8x8的棋盘图形矩阵
Z = np.zeros((8, 8), dtype=int)
Z[1::2, ::2] = 1
Z[::2, 1::2] = 1
print(Z)
# 知识点:棋盘图案
# 解析:使用切片操作创建一个8x8的棋盘图形矩阵,交替填充1和0。
# 19. 对于一个形如(6,7,8)的数组,第100个元素索引的(x,y,z)是什么
print(np.unravel_index(100, (6, 7, 8)))
# 知识点:多维数组索引
# 解析:使用`np.unravel_index`函数将线性索引转换为多维数组的索引。
# 20. 使用tile函数创建一个8x8的棋盘
Z = np.tile(np.array([[0, 1], [1, 0]]), (4, 4))
print(Z)
# 知识点:tile函数
# 解析:使用`np.tile`函数将一个2x2的小棋盘图案重复4次,形成一个8x8的棋盘图案。
# 21. 将5x5的随机矩阵标准化
Z = np.random.random((5, 5))
Z = (Z - np.mean(Z)) / np.std(Z)
print(Z)
# 知识点:矩阵标准化
# 解析:使用均值和标准差对矩阵进行标准化,使得每个元素减去均值后除以标准差。
# 22. 创建一个自定义类型表示一种由四个无符号字节组成的颜色(RGBA)
color = np.dtype([("r", np.ubyte, 1),
("g", np.ubyte, 1),
("b", np.ubyte, 1),
("a", np.ubyte, 1)])
# 知识点:自定义数据类型
# 解析:使用`np.dtype`定义一个包含4个无符号字节(r, g, b, a)的自定义数据类型。
# 23. 5x3的矩阵和3x2的矩阵相乘(矩阵乘法)
Z = np.dot(np.ones((5, 3)), np.ones((3, 2)))
print(Z)
# 知识点:矩阵乘法
# 解析:使用`np.dot`函数进行矩阵乘法,将一个5x3的全1矩阵与一个3x2的全1矩阵相乘。
# 24. 给定一个一维数组,将(3, 8)之间的元素原地变为负数
Z = np.arange(11)
Z[(3 < Z) & (Z <= 8)] *= -1
print(Z)
# 知识点:布尔索引
# 解析:使用布尔索引筛选出数组中值在3到8之间的元素,并将其原地变为负数。
# 25. 下列代码输出是什么
print(sum(range(5),-1))
# 解析:`sum(range(5), -1)`返回9,因为`range(5)`是[0, 1, 2, 3, 4],加上-1的起始值。
from numpy import *
print(sum(range(5),-1))
# 解析:`sum`函数来自Numpy库,第二个参数表示轴,而不是起始值,结果是10。
# 知识点:Python内置sum函数和Numpy sum函数的区别
# 26. 对于一个整数向量Z,下列表示哪些是合法的
Z = np.arange(5)
print(Z**Z) # 合法,返回[1, 1, 4, 27, 256]
print(2 << Z >> 2) # 合法,返回[0, 1, 2, 4, 8]
print(Z <- Z) # 合法,返回[False, False, False, False, False]
print(1j*Z) # 合法,返回[0.+0.j, 0.+1.j, 0.+2.j, 0.+3.j, 0.+4.j]
print(Z/1/1) # 合法,返回[0. 1. 2. 3. 4.]
# print(Z<Z>Z) # 不合法,会引发错误
# 知识点:Numpy的基本运算
# 27. 下列表达式的结果是什么
print(np.array(0) / np.array(0)) # nan
print(np.array(0) // np.array(0)) # 0,警告:除以零
print(np.array([np.nan]).astype(int).astype(float)) # [-9.22337204e+18]
# 知识点:特殊值处理和类型转换
# 28. 如何让一个浮点数数组四舍五入
Z = np.random.uniform(0, 10, 10)
print(np.round(Z))
# 知识点:四舍五入
# 解析:使用`np.round`函数对浮点数数组进行四舍五入。
# 29. 如何找到两个数组中的共同值
Z1 = np.random.randint(0, 10, 10)
Z2 = np.random.randint(0, 10, 10)
print(np.intersect1d(Z1, Z2))
# 知识点:数组交集
# 解析:使用`np.intersect1d`函数找到两个数组中的共同值。
# 30. 如何忽略所有numpy警告(不推荐)
defaults = np.seterr(all="ignore")
Z = np.ones(1) / 0
# 知识点:忽略警告
# 解析:使用`np.seterr(all="ignore")`忽略所有Numpy警告,不推荐使用。
# 31. 下列表达式是正确的吗
print(np.sqrt(-1) == np.emath.sqrt(-1)) # False
# 知识点:复数计算
# 解析:`np.sqrt(-1)`返回nan,而`np.emath.sqrt(-1)`返回1j,二者不相等。
# 32. 如何得到昨天、今天和明天的日期
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, today, tomorrow)
# 知识点:日期计算
# 解析:使用`np.datetime64`和`np.timedelta64`进行日期计算,得到昨天、今天和明天的日期。
# 33. 如何得到2016年7月每一天的日期
Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')
print(Z)
# 知识点:日期范围
# 解析:使用`np.arange`生成一个包含2016年7月每一天的日期数组。
# 34. 如何原地计算((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)
# 知识点:原地操作
# 解析:使用`np.add`、`np.divide`、`np.negative`和`np.multiply`函数的`out`参数进行原地操作,避免复制。
# 35. 使用四种不同的方法从一个随机正数数组中找出整数
Z = np.random.uniform(0, 10, 10)
print(Z - Z % 1) # 方法1:取整
print(np.floor(Z)) # 方法2:向下取整
print(np.ceil(Z)-1) # 方法3:向上取整减1
print(Z.astype(int)) # 方法4:类型转换
# 知识点:取整操作
# 解析:使用四种不同的方法从随机正数数组中取整:取整、向下取整、向上取整减1、类型转换。
# 36. 创建一个5x5的矩阵,每行的值从0到4
Z = np.zeros((5, 5))
Z += np.arange(5)
print(Z)
# 知识点:数组广播
# 解析:使用`np.arange(5)`生成一个包含0到4的向量,并通过广播将其加到5x5的零矩阵的每一行。
# 37. 定义一个生成函数,它可以产生10个整数并构建一个数组
def generate():
for x in range(10):
yield x
Z = np.fromiter(generate(), dtype=float, count=-1)
print(Z)
# 知识点:生成器函数
# 解析:定义一个生成器函数`generate`,它产生10个整数,并使用`np.fromiter`函数将生成器的结果构建为数组。
# 38. 创建一个大小为10的向量,其值为(0, 1)
Z = np.linspace(0, 1, 10, endpoint=False)[1:]
print(Z)
# 知识点:线性间隔
# 解析:使用`np.linspace`生成一个包含10个值的向量,其值在0到1之间,`endpoint=False`表示不包含终点1。
# 39. 创建一个大小为10的随机向量并排序
Z = np.random.random(10)
Z.sort()
print(Z)
# 知识点:数组排序
# 解析:使用`np.random.random(10)`生成一个包含10个元素的随机向量,并使用`sort`方法对其进行排序。
# 40. 对一个小数组求和如何快过np.sum
Z = np.arange(10)
print(np.add.reduce(Z))
# 知识点:数组求和
# 解析:使用`np.add.reduce`函数对小数组进行求和,通常比`np.sum`更快。
# 41. 判断两个随机数组A和B是否相等
A = np.random.randint(0, 2, 5)
B = np.random.randint(0, 2, 5)
equal = np.array_equal(A, B)
print(equal)
# 知识点:数组比较
# 解析:使用`np.array_equal`函数判断两个随机数组是否相等。
# 42. 创建一个不可改变(只读)的数组
Z = np.zeros(10)
Z.flags.writeable = False
# Z[0] = 1 # 试图修改只读数组会引发错误
# 知识点:只读数组
# 解析:将数组的`writeable`标志设置为False,使其变为只读。
# 43. 创建一个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, T)
# 知识点:笛卡尔坐标系与极坐标系转换
# 解析:使用笛卡尔坐标系的公式`R = sqrt(X^2 + Y^2)`和`T = arctan2(Y, X)`将其转换为极坐标系。
# 44. 创建一个大小为10的随机向量,将最大值替换为0
Z = np.random.random(10)
Z[Z.argmax()] = 0
print(Z)
# 知识点:数组元素替换
# 解析:使用`argmax`函数找到数组中的最大值索引,并将该索引处的值替换为0。
# 45. 创建一个结构化数组,并分别将x和y坐标覆盖表示坐标(x,y)
Z = np.zeros(10, [ ('position', [ ('x', float, 1), ('y', float, 1)])])
print(Z)
# 知识点:结构化数组
# 解析:使用结构化数据类型定义一个包含x和y坐标的数组。
# 46. 打印每个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)
# 知识点:数据类型范围
# 解析:使用`np.iinfo`和`np.finfo`函数打印每个标量类型的最小值和最大值。
# 47. 打印numpy加法减法乘法除法之间的错误
np.seterr(all='ignore')
np.seterr(over='warn', under='ignore', invalid='warn', divide='warn')
# 知识点:设置错误处理
# 解析:使用`np.seterr`函数设置Numpy的错误处理方式,忽略所有错误并仅对特定类型的错误进行警告。
# 48. 将随机生成的二维数组按行、列堆叠
A = np.random.randint(0, 10, (2, 2))
B = np.random.randint(0, 10, (2, 2))
print(np.vstack((A, B)))
print(np.hstack((A, B)))
# 知识点:数组堆叠
# 解析:使用`np.vstack`进行按行堆叠,`np.hstack`进行按列堆叠。
# 49. 在一个二维数组的每一行中找到最大值
Z = np.random.randint(0, 10, (4, 4))
print(np.max(Z, axis=1))
# 知识点:二维数组处理
# 解析:使用`np.max`函数并指定`axis=1`,在二维数组的每一行中找到最大值。
# 50. 如何计算一个大数组的内存消耗
Z = np.zeros((100, 100))
print("%d bytes" % (Z.size * Z.itemsize))
# 知识点:内存消耗计算
# 解析:通过`Z.size`获取数组元素数量,`Z.itemsize`获取每个元素的字节数,计算内存消耗。