NumPy 快速入门教程

什么是 NumPy?

NumPy 是 Python 科学计算的基础包。它提供了一个强大的多维数组对象(ndarray),以及各种派生对象(如掩码数组、矩阵)和一系列用于快速操作数组的函数,涵盖了数学、逻辑、形状操作、排序、选择、I/O、离散傅里叶变换、线性代数、统计、随机模拟等方方面面。

NumPy 的核心是 ndarray 对象,它是一个由同质数据元素组成的 n 维数组。为了提高性能,许多操作都是在经过高度优化的编译代码(C/C++)中执行的。


NumPy 数组与 Python 列表(List)的重要区别

特性 NumPy 数组 (ndarray) Python 列表 (list)
大小 创建时固定,改变大小会创建新数组并删除原数组 可以动态增长
数据类型 所有元素类型必须相同(同质) 可以包含不同类型元素
运算效率 高度优化的预编译代码,执行速度快 Python 循环,速度慢
语法简洁性 向量化操作,代码简洁 通常需要显式循环

越来越多的科学/数学 Python 包都基于 NumPy 数组构建,因此掌握 NumPy 是高效使用这些工具的前提。


数组大小与速度:为什么科学计算离不开 NumPy?

考虑一个简单的任务:将两个一维序列的对应元素相乘。

如果数据存储在 Python 列表 ab 中,通常我们会这样写:

c = []
for i in range(len(a)):
    c.append(a[i] * b[i])

当数据量达到数百万时,Python 循环的低效就会成为瓶颈。同样的计算在 C 语言中可以这样写:

for (i = 0; i < rows; i++) {
  c[i] = a[i] * b[i];
}

C 代码速度快,但编写繁琐。对于二维数组,C 代码会变成双重循环,复杂度进一步增加。

NumPy 给出了两全其美的解决方案:通过向量化操作,我们可以用一行简洁的 Python 代码实现 C 语言级别的速度:

c = a * b

这行代码背后,NumPy 在预编译的 C 代码中执行了逐元素乘法,既保持了 Python 的简洁,又获得了接近 C 的性能。

这个例子展示了 NumPy 的两个核心特性:向量化(Vectorization)和广播(Broadcasting)。


为什么 NumPy 这么快?

向量化(Vectorization)

向量化指的是代码中没有显式的循环、索引等操作,所有的循环都在后台由优化的 C 代码完成。其优点包括:

  • 代码更简洁、更易读
  • 更少出错(行数越少,bug 越少)
  • 更贴近数学表达
  • 更符合 Pythonic 风格

广播(Broadcasting)

广播是 NumPy 在执行操作时,自动扩展较小数组以匹配较大数组形状的机制。它不仅适用于算术运算,还适用于逻辑、位运算、函数调用等所有操作。

例如,标量 3 可以和一个数组相加,NumPy 会自动将 3 广播到数组的每个元素:

a = np.array([1, 2, 3])
print(a + 3)   # 输出 [4 5 6]

广播也适用于不同形状的数组,只要它们在某些维度上兼容。


谁在使用 NumPy?

NumPy 的 ndarray 已经成为 Python 中多维数据交换的事实标准。它支持面向对象(通过 ndarray 的方法)和函数式(通过 NumPy 顶层函数)两种编程风格,灵活强大。


NumPy 基础知识

ndarray 的核心属性

  • ndarray.ndim:数组轴(维度)的数量。
  • ndarray.shape:数组的维度,是一个表示每个轴大小的元组。例如,一个 n 行 m 列的矩阵,shape(n, m)
  • ndarray.size:数组中元素的总个数,等于 shape 中各元素的乘积。
  • ndarray.dtype:描述数组元素类型的对象。可以是 Python 内置类型,也可以是 NumPy 提供的类型,如 numpy.int32numpy.float64 等。
  • ndarray.itemsize:数组中每个元素的字节大小。例如,float64itemsize 为 8。
  • ndarray.data:包含数组实际元素的缓冲区。通常我们通过索引访问元素,很少直接使用这个属性。
示例
import numpy as np

# 创建一个 0~14 的数组,并重塑为 3 行 5 列
a = np.arange(15).reshape(3, 5)
print(a)
# [[ 0  1  2  3  4]
#  [ 5  6  7  8  9]
#  [10 11 12 13 14]]

print(a.shape)      # (3, 5)
print(a.ndim)       # 2
print(a.dtype.name) # 'int64' (可能因平台而异)
print(a.itemsize)   # 8
print(a.size)       # 15
print(type(a))      # <class 'numpy.ndarray'>

# 一维数组
b = np.array([6, 7, 8])
print(b)            # [6 7 8]

数组创建

1. 从 Python 序列转换(np.array

a = np.array([2, 3, 4])          # 从列表创建,dtype 自动推断为 int64
b = np.array([1.2, 3.5, 5.1])    # 自动推断为 float64
c = np.array([(1.5, 2, 3), (4, 5, 6)])  # 二维数组
d = np.array([[1, 2], [3, 4]], dtype=complex)  # 指定数据类型

常见错误np.array(1,2,3,4) 是错误的,应该传入一个列表:np.array([1,2,3,4])

2. 使用占位符创建

当数组大小已知但元素未知时,可以用以下函数创建初始占位符数组:

  • np.zeros(shape):全 0 数组(默认 float64
  • np.ones(shape):全 1 数组
  • np.empty(shape):内容随机的数组(取决于内存状态)
np.zeros((3, 4))                 # 3行4列的全0数组
np.ones((2, 3, 4), dtype=np.int16)  # 2x3x4 的三维数组,int16 类型
np.empty((2, 3))                 # 未初始化的 2x3 数组

3. 创建数值序列

  • np.arange(start, stop, step):类似于 Python 的 range,但返回数组。当使用浮点数步长时,推荐用 linspace
  • np.linspace(start, stop, num):在指定区间内生成固定数量的点。
np.arange(10, 30, 5)        # array([10, 15, 20, 25])
np.arange(0, 2, 0.3)        # 浮点数步长可能产生不可预测的个数
np.linspace(0, 2, 9)        # 在0到2之间生成9个数

打印数组

NumPy 打印数组时,会按照以下规则布局:

  • 最后一个轴从左到右打印
  • 倒数第二个轴从上到下打印
  • 其余轴从上到下打印,每个切片之间用空行隔开
# 一维数组
a = np.arange(6)
print(a)   # [0 1 2 3 4 5]

# 二维数组
b = np.arange(12).reshape(4, 3)
print(b)
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

# 三维数组
c = np.arange(24).reshape(2, 3, 4)
print(c)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

当数组太大时,NumPy 会自动省略中间部分:

print(np.arange(10000))       # 显示 [   0    1    2 ... 9997 9998 9999]

若要强制打印整个数组,可以设置打印选项:

import sys
np.set_printoptions(threshold=sys.maxsize)

基本运算

逐元素运算

算术运算符(+-*/** 等)默认对数组执行逐元素操作。

a = np.array([20, 30, 40, 50])
b = np.arange(4)               # array([0, 1, 2, 3])

c = a - b                      # array([20, 29, 38, 47])
print(b ** 2)                  # array([0, 1, 4, 9])
print(10 * np.sin(a))          # 逐元素应用正弦函数
print(a < 35)                  # array([ True,  True, False, False])

矩阵乘法

乘法运算符 * 是逐元素乘法,矩阵乘法使用 @ 运算符或 dot() 方法。

A = np.array([[1, 1], [0, 1]])
B = np.array([[2, 0], [3, 4]])

print(A * B)      # 逐元素乘法:[[2, 0], [0, 4]]
print(A @ B)      # 矩阵乘法:[[5, 4], [3, 4]]
print(A.dot(B))   # 同上

原地操作

运算符 +=*= 等会直接修改原数组,不会创建新数组。

rg = np.random.default_rng(1)
a = np.ones((2, 3), dtype=int)
b = rg.random((2, 3))

a *= 3            # a 的每个元素乘以 3
b += a            # 将 a 加到 b 上(需要类型兼容)

注意:类型向下转换是不允许的。例如,a += ba 是 int,b 是 float)会报错。

类型提升

对不同类型的数组进行操作时,结果类型会自动提升到更通用的类型。

a = np.ones(3, dtype=np.int32)
b = np.linspace(0, np.pi, 3)   # float64
c = a + b
print(c.dtype)                  # float64

d = np.exp(c * 1j)
print(d.dtype)                  # complex128

一元操作

许多一元操作(如求和、最小值、最大值)是 ndarray 的方法。

a = rg.random((2, 3))
print(a.sum())      # 所有元素之和
print(a.min())      # 最小值
print(a.max())      # 最大值

通过 axis 参数可以沿指定轴操作:

  • axis=0:沿纵向(跨行),结果中列数不变,行数变为 1(或消失)
  • axis=1:沿横向(跨列),结果中行数不变,列数变为 1(或消失)
b = np.arange(12).reshape(3, 4)
print(b.sum(axis=0))      # 每列之和:[12 15 18 21]
print(b.min(axis=1))      # 每行最小值:[0 4 8]
print(b.cumsum(axis=1))   # 每行的累加和

通用函数(ufunc)

NumPy 提供了许多数学函数,如 sincosexpsqrt 等,它们被称为“通用函数”(ufunc),对数组进行逐元素运算。

B = np.arange(3)
np.exp(B)          # e^0, e^1, e^2
np.sqrt(B)         # 开方
C = np.array([2., -1., 4.])
np.add(B, C)       # 相当于 B + C

常用 ufunc 可分为以下几类:

  • 数学处理floor, ceil, round, clip, conj
  • 统计分析sum, mean, median, std, var, average
  • 排序搜索sort, argsort, argmax, argmin, where, nonzero
  • 线性代数dot, vdot, trace, transpose, outer, cross
  • 逻辑判定all, any

索引、切片和迭代

一维数组

与 Python 列表类似,支持索引、切片和迭代。

a = np.arange(10) ** 3
print(a[2])          # 8
print(a[2:5])        # [8, 27, 64]
a[:6:2] = 1000       # 从开头到第6个元素,每隔2个元素赋值为1000
print(a[::-1])       # 反转数组

多维数组

每个轴用一个索引,索引之间用逗号分隔。

def f(x, y):
    return 10 * x + y

b = np.fromfunction(f, (5, 4), dtype=int)
print(b[2, 3])        # 第3行第4列
print(b[0:5, 1])      # 所有行的第2列
print(b[1:3, :])      # 第2到3行的所有列

省略号(... 表示多个完整的切片:

  • x[1, 2, ...] 等价于 x[1, 2, :, :, :]
  • x[..., 3] 等价于 x[:, :, :, :, 3]

迭代

多维数组默认按第一个轴(行)迭代:

for row in b:
    print(row)        # 逐行打印

使用 flat 属性可以获取一个遍历所有元素的迭代器:

for element in b.flat:
    print(element)    # 遍历每个元素

形状操纵

改变数组形状

  • ravel():将数组展平为一维(返回视图,除非必要)。
  • reshape():改变形状,返回新数组(不修改原数组)。
  • resize():就地修改形状。
  • T:转置。
a = np.floor(10 * rg.random((3, 4)))
a.ravel()                 # 展平
a.reshape(6, 2)           # 重塑为 6x2
a.T                       # 转置
a.resize((2, 6))          # 就地改变形状

使用 -1 自动推断维度:

a.reshape(3, -1)          # 自动计算列数

堆叠数组

  • vstack():垂直堆叠(沿行)
  • hstack():水平堆叠(沿列)
  • column_stack():将一维数组作为列堆叠
  • row_stack():等价于 vstack
a = np.floor(10 * rg.random((2, 2)))
b = np.floor(10 * rg.random((2, 2)))
np.vstack((a, b))
np.hstack((a, b))

# column_stack 示例
from numpy import newaxis
a = np.array([4., 2.])
b = np.array([3., 8.])
np.column_stack((a, b))   # 返回 2x2 数组
a[:, newaxis]             # 将一维数组转换为列向量

np.r_np.c_ 提供了更灵活的堆叠方式:

np.r_[1:4, 0, 4]          # array([1, 2, 3, 0, 4])

拆分数组

  • hsplit():水平拆分
  • vsplit():垂直拆分
  • array_split():可指定轴
a = np.floor(10 * rg.random((2, 12)))
np.hsplit(a, 3)            # 平均拆分为3份
np.hsplit(a, (3, 4))       # 在第3列和第4列之后拆分

拷贝与视图

1. 完全不拷贝(No Copy)

简单赋值不会创建新对象,只是给原数组加了一个新名字。

a = np.array([[1,2],[3,4]])
b = a
print(b is a)       # True

函数传递也是引用,不会发生拷贝。

2. 视图或浅拷贝(View/Shallow Copy)

  • view():创建一个新数组对象,但共享底层数据。
  • 切片:返回的也是视图。
c = a.view()
print(c is a)       # False
print(c.base is a)  # True(c 是 a 的视图)

s = a[:, 1:3]
s[:] = 10           # 修改 s 会同时修改 a

3. 深拷贝(Deep Copy)

  • copy():创建完全独立的数组副本,不共享数据。
d = a.copy()
d[0,0] = 999        # 修改 d 不影响 a

内存提示:如果从一个巨大的数组中切片一小部分并希望释放大数组,务必使用 copy()。例如:

b = a[:100].copy()   # 独立的小数组,原数组 a 可被释放
del a                # 释放内存

常用函数与方法速查

数组创建

arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r_, c_, zeros, zeros_like

类型转换

ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat

形状操作

array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack

逻辑判断

all, any, nonzero, where

排序与搜索

argmax, argmin, argsort, max, min, ptp, searchsorted, sort

运算

choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum

统计与线性代数

  • 统计cov, mean, std, var
  • 线性代数cross, dot, outer, linalg.svd, vdot

NumPy 常用函数速查表

按功能分类,附简洁示例,方便你随时查阅。

1. 数组创建

函数 说明 示例
np.array([1,2,3]) 从列表或元组创建数组 a = np.array([1,2,3])
np.zeros((3,4)) 创建全0数组,参数为形状 np.zeros((2,3)) → 2行3列的全0矩阵
np.ones((2,2)) 创建全1数组 np.ones((2,2))
np.empty((2,3)) 创建未初始化数组(值随机) 性能高,但值不确定
np.arange(0,10,2) 类似Python range,生成等差数列 np.arange(0,10,2)[0,2,4,6,8]
np.linspace(0,1,5) 生成指定间隔内的等间隔数 np.linspace(0,1,5)[0. , 0.25, 0.5 , 0.75, 1. ]
np.random.rand(3,2) 生成[0,1)均匀分布的随机数 3行2列
np.random.randn(3,2) 生成标准正态分布的随机数 均值为0,方差为1
np.random.randint(0,10,(3,3)) 生成随机整数 范围[0,10),形状3x3
np.eye(4) 创建单位矩阵 4x4对角线上为1

2. 数组属性

属性 说明 示例
arr.shape 返回数组形状元组 (3,4)
arr.dtype 返回元素数据类型 int64, float32
arr.size 返回元素总数 等于各维度乘积
arr.ndim 返回数组维度数 1维、2维等
arr.T 转置(仅对2维有效) 相当于 arr.transpose()

3. 数组操作

函数 说明 示例
arr.reshape(2,3) 改变形状,不改变数据 原数组必须大小匹配
arr.resize(2,3) 改变形状,会修改原数组 与reshape不同,直接修改
arr.flatten() 展平为一维数组(返回副本) 按行优先
arr.ravel() 展平为一维数组(返回视图,节省内存) 修改视图可能影响原数组
np.concatenate([a,b], axis=0) 沿指定轴拼接数组 axis=0按行堆叠,axis=1按列
np.vstack((a,b)) 垂直堆叠(行增加) 等价于axis=0的concatenate
np.hstack((a,b)) 水平堆叠(列增加) 等价于axis=1的concatenate
np.split(arr, 3, axis=0) 将数组分割成子数组 指定份数或分割位置
np.transpose(arr, axes) 转置或重排轴 对于高维数组有用

4. 数学运算

函数/操作 说明 示例
+ - * / 逐元素运算(广播机制) a + b 对应元素相加
np.sqrt(arr) 开平方 也可用 arr**0.5
np.exp(arr) 指数e^x
np.log(arr) 自然对数 np.log10(arr) 以10为底
np.sin(arr) 三角函数 cos, tan
@np.dot(a,b) 矩阵乘法(不是逐元素乘) a @ b
np.power(arr, 3) 幂运算 也可用 arr**3
np.abs(arr) 绝对值

5. 统计函数

函数 说明 示例
np.sum(arr) 求和 axis参数指定维度,如 np.sum(arr, axis=0) 按列求和
np.mean(arr) 平均值
np.median(arr) 中位数
np.min(arr) 最小值 np.max 最大值
np.std(arr) 标准差 np.var 方差
np.argmin(arr) 最小值索引 np.argmax 最大值索引
np.cumsum(arr) 累积和 返回数组
np.percentile(arr, 75) 计算百分位数 75%分位数

6. 索引与切片

语法 说明 示例
arr[i] 取第i行(对二维数组)
arr[i, j] 取第i行第j列元素
arr[1:3, :] 切片:行1到2,所有列 左闭右开
arr[arr > 5] 布尔索引:选取大于5的元素 返回一维数组
arr[[0,2], :] 花式索引:取第0行和第2行 可指定行列表
arr[:, [1,3]] 取所有行的第1列和第3列

7. 线性代数(np.linalg

函数 说明 示例
np.linalg.inv(a) 矩阵求逆 a必须为方阵且可逆
np.linalg.det(a) 行列式
np.linalg.eig(a) 特征值和特征向量 返回元组 (特征值, 特征向量)
np.linalg.solve(a, b) 解线性方程组 a x = b
np.linalg.qr(a) QR分解
np.linalg.svd(a) 奇异值分解

8. 其他实用函数

函数 说明 示例
np.where(condition, x, y) 根据条件从x或y中取值 np.where(arr>0, arr, 0) 将负数变0
np.unique(arr) 去重并排序 返回唯一值数组
np.sort(arr) 排序 axis指定轴,np.argsort返回排序索引
np.clip(arr, a_min, a_max) 将值限制在[a_min, a_max]之间 小于a_min的变a_min,大于a_max的变a_max
np.save('file.npy', arr) 保存数组到二进制文件 np.load('file.npy') 读取
np.savetxt('file.csv', arr, delimiter=',') 保存为文本文件 np.loadtxt('file.csv', delimiter=',') 读取

小贴士

  • 想查看函数的完整文档?在Jupyter里输入 np.mean?help(np.mean) 即可。
  • 多用 axis 参数,它控制操作沿着哪个维度进行,是NumPy的精髓。
  • 遇到“广播”不理解?记住:NumPy会自动将小数组扩展到大数组的形状,只要维度兼容。

这份速查表涵盖了日常使用频率最高的NumPy函数。建议你把这些示例在Jupyter Notebook里敲一遍,边敲边体会。当你用Pandas处理数据时,很多底层操作仍然依赖NumPy,扎实的基础会让你的数据分析之路越走越顺。

接下来你可以尝试用NumPy做一些小练习,比如生成随机矩阵并计算统计量、模拟简单线性回归等。


你这份NumPy速查表整理得非常全面,涵盖了日常工作中95%以上的常用功能。可以说,掌握这张表的内容,就已经能非常从容地应对绝大多数数据分析、科学计算和面试场景了。

✅ 你已经覆盖的核心领域

从你的速查表分类来看,它已经完整包含了以下关键模块:

  1. 数组创建:从基础的arrayzeros,到序列生成arange/linspace,再到随机数rand/randint,一应俱全。
  2. 数组属性与操作shapedtype等属性,以及reshapeflatten、各种堆叠拼接(vstack/hstack),都是日常高频使用的。
  3. 数学与统计:逐元素运算、矩阵乘法@、统计函数(sum/mean/std)和基础线性代数(inv/det/solve)都已覆盖。
  4. 索引与切片:普通索引、切片、布尔索引、花式索引这些核心技巧都列出来了。
  5. 实用函数whereuniqueclip、文件读写save/loadtxt等,都是非常实用的工具。

🔍 查漏补缺:可能还需要了解的一些补充点

类别 补充函数/概念 说明与示例
高级索引 np.take(a, indices) 沿轴取元素,类似花式索引,但某些场景下性能更好。
np.take(arr, [0,2], axis=1)
np.ix_ 构造开放网格,用于组合多个索引数组进行花式索引。
arr[np.ix_([0,2], [1,3])]
数组操作 np.roll(a, shift) 循环移动数组元素。
np.roll([1,2,3,4], 1)[4,1,2,3]
np.flip(a, axis) 沿指定轴翻转数组顺序。
np.flip(arr, axis=0) 上下翻转行。
np.repeat(a, repeats) 重复数组元素。
np.repeat([1,2], 3)[1,1,1,2,2,2]
np.tile(a, reps) 平铺数组来构造更大的数组。
np.tile([1,2], (2,2)) 生成2x2的平铺矩阵。
数学运算 np.cross(a, b) 计算两个向量的叉积。
np.outer(a, b) 计算两个向量的外积。
np.angle(z) / np.real / np.imag 复数操作:计算辐角、实部、虚部。
逻辑与集合 np.isin(a, b) 判断a的元素是否在b中,返回布尔数组。
np.isin([1,2,3], [2,4])[False, True, False]
np.intersect1d / union1d / setdiff1d 集合操作(虽然unique常用,但专门集合函数也很方便)。
随机数 np.random.choice(a, size, p) 从一维数组中随机抽取元素,可指定概率p。
np.random.choice(['A','B'], 10, p=[0.3,0.7])
np.random.shuffle(a) 就地随机打乱数组顺序。
底层与性能 np.einsum(subscripts, *operands) 爱因斯坦求和约定,是一种极其强大(但稍复杂)的方式来表达各种数组运算(如矩阵乘法、转置、求和等)。
np.einsum('ij,jk->ik', A, B) 等价于 A @ B
np.may_share_memory(a, b) 检查两个数组是否共享内存(即是否是视图关系)。

NumPy 练习题(共50题)

说明:以下练习题旨在帮助你掌握 NumPy 的核心功能。请尽量在不查答案的情况下独立完成,每道题建议在 Jupyter Notebook 中实际运行验证。题目难度逐渐增加,部分题目可能需要结合多个知识点。


基础篇(1-15题):数组创建、属性、基本操作
  1. 导入 NumPy 库,并查看版本号。

  2. 创建一个长度为 10 的一维全零数组。

  3. 创建一个形状为 (3,4) 的全一数组,并指定数据类型为 int32。

  4. 创建一个 3x3 的单位矩阵。

  5. 创建一个从 10 到 49 的一维数组。

  6. 创建一个 2x5 的数组,元素为 0 到 9(按行填充)。

  7. 创建一个长度为 100 的等间隔数列,范围从 0 到 1(包含端点)。

  8. 创建一个 4x4 的随机数组(均匀分布),并打印其形状、维度和数据类型。

  9. 创建一个 5x5 的随机整数数组,取值范围在 [0, 10) 之间。

  10. 将上题生成的数组的所有元素转换为 float64 类型。

  11. 创建一个长度为 20 的一维数组,元素全为 0,然后将第 5 个元素(索引从0开始)改为 1。

  12. 创建一个 3x3 的数组,元素为 1 到 9,并求出所有元素的和。

  13. 创建一个 4x4 的对角矩阵,对角线元素为 1,2,3,4。

  14. 生成一个 3x3 的标准正态分布随机数组。

  15. 创建一个 5 元素的一维数组,并访问其最后三个元素。


索引与切片篇(16-25题)
  1. 创建一个 6x6 的随机整数数组,元素范围在 0-100,提取出第 2 行(索引从0开始)。

  2. 从上述数组中提取第 3 列的所有元素。

  3. 提取上述数组的左上角 3x3 子矩阵。

  4. 将上述数组的所有奇数行和偶数列的元素取出。

  5. 创建一个 4x4 的数组,将其第 1 行和第 3 行交换。

  6. 创建一个 8x8 的数组,用 0 和 1 填充成棋盘格样式(0 在 (0,0) 位置)。

  7. 创建一个一维数组 arr = np.array([1,2,3,4,5,6,7,8,9]),将其索引为奇数的元素替换为 -1。

  8. 创建一个 5x5 的随机数组,找出所有大于 0.5 的元素,并将它们赋值为 1。

  9. 创建一个 10x10 的随机数组,找到每一行的最大值位置(列索引)。

  10. 创建一个 3x4 的数组,使用花式索引提取第 0 行和第 2 行,以及第 1 列和第 3 列(结果应为 2x2 矩阵)。


形状操作与广播篇(26-35题)
  1. 创建一个 1x6 的一维数组,然后将其重塑为 2x3 的二维数组。

  2. 创建一个 2x3x4 的三维随机数组,将其展平为一维。

  3. 创建两个形状分别为 (3,1) 和 (1,4) 的数组,利用广播机制计算它们的和,结果形状为 (3,4)。

  4. 创建一个长度为 10 的一维数组,将其形状变为 (2,5),然后再转置。

  5. 创建一个 5x5 的数组,将第 1 行与第 2 行垂直堆叠(不修改原数组)。

  6. 创建两个 3x3 的随机数组 A 和 B,将它们水平拼接(列数增加)。

  7. 将数组 np.array([1,2,3]) 沿着新轴变成列向量(形状 (3,1))和行向量(形状 (1,3))。

  8. 创建一个 4x4 数组,使用 resize 将其变为 2x8(注意 resizereshape 的区别)。

  9. 创建两个一维数组 a 和 b,长度分别为 5 和 3,通过广播实现外积(结果形状 (5,3))。

  10. 创建一个 3x3 数组,将其每一行减去该行的平均值。


数学运算与统计篇(36-45题)
  1. 创建一个 4x4 随机整数数组,计算所有元素的均值、标准差和方差。

  2. 计算上述数组每列的和,以及每行的最大值。

  3. 创建一个 5x5 数组,计算其对角线元素的和(主对角线)。

  4. 计算数组 np.array([[1,2],[3,4]])np.array([[5,6],[7,8]]) 的矩阵乘积(点积)。

  5. 创建一个 3x3 的随机矩阵,求它的逆矩阵(假设可逆)。

  6. 解线性方程组:
    x + 2y = 5
    3
    x + 4*y = 6
    使用 NumPy 求解。

  7. 计算数组 np.array([1,2,3,4]) 的累积和。

  8. 创建一个 10x10 的随机数组,找到全局最小值的位置(索引)。

  9. 创建一个 3x4 的数组,计算每行的最大值与最小值之差(极差)。

  10. 对数组 np.array([[3,1,2],[6,4,5]]) 按列排序(升序)。


进阶与综合篇(46-50题)
  1. 创建一个 1000 个元素的一维随机数组,找出其中出现频率最高的值(众数)。如果有多个众数,返回最小的那个。

  2. 实现一个简单的移动平均函数,输入一维数组和窗口大小 k,返回移动平均值数组(长度与原数组相同,前 k-1 个元素可用 NaN 填充)。

  3. 创建一个 20x20 的随机数组,使用布尔索引将所有大于 0.5 的元素替换为 NaN,并计算剩余元素的均值。

  4. 生成一个 5x5 的随机整数矩阵,计算其特征值和特征向量。

  5. 模拟一个 1000 次投掷两枚骰子的实验,统计点数之和的分布(直方图),并找出最可能出现的和。


答案部分

1. 导入 NumPy 并查看版本号

import numpy as np
print(np.__version__)

2. 长度为 10 的全零数组

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

3. 形状 (3,4) 的全一数组,int32 类型

arr = np.ones((3,4), dtype=np.int32)
print(arr)

4. 3x3 单位矩阵

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

5. 从 10 到 49 的一维数组

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

6. 2x5 数组,元素 0-9 按行填充

arr = np.arange(10).reshape(2,5)
print(arr)

7. 从 0 到 1 的等间隔数列,长度 100

arr = np.linspace(0, 1, 100)
print(arr)

8. 4x4 均匀分布随机数组,打印属性

arr = np.random.rand(4,4)
print("形状:", arr.shape)
print("维度:", arr.ndim)
print("数据类型:", arr.dtype)

9. 5x5 随机整数数组 [0,10)

arr = np.random.randint(0, 10, size=(5,5))
print(arr)

10. 将上题数组转换为 float64

arr_float = arr.astype(np.float64)
print(arr_float.dtype)

11. 长度为 20 的零数组,将第 5 个元素改为 1

arr = np.zeros(20)
arr[5] = 1
print(arr)

12. 3x3 数组 1-9,求和

arr = np.arange(1,10).reshape(3,3)
total = np.sum(arr)
print(total)

13. 4x4 对角矩阵,对角线元素 1,2,3,4

arr = np.diag([1,2,3,4])
print(arr)

14. 3x3 标准正态分布随机数组

arr = np.random.randn(3,3)
print(arr)

15. 一维数组,访问最后三个元素

arr = np.array([10,20,30,40,50])
print(arr[-3:])

16. 提取第 2 行(索引从0开始)

arr = np.random.randint(0,100,size=(6,6))
row2 = arr[2,:]
print(row2)

17. 提取第 3 列

col3 = arr[:,3]
print(col3)

18. 左上角 3x3 子矩阵

sub = arr[:3, :3]
print(sub)

19. 奇数行和偶数列

# 奇数行:索引1,3,5...;偶数列:索引0,2,4...
result = arr[1::2, ::2]
print(result)

20. 交换第 1 行和第 3 行

arr = np.random.randint(0,10,size=(4,4))
arr[[0,2]] = arr[[2,0]]   # 索引0和2对应第1行和第3行
print(arr)

21. 8x8 棋盘格

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

22. 将奇数索引元素替换为 -1

arr = np.array([1,2,3,4,5,6,7,8,9])
arr[1::2] = -1
print(arr)

23. 大于 0.5 的元素赋值为 1

arr = np.random.rand(5,5)
arr[arr > 0.5] = 1
print(arr)

24. 每行最大值的位置

arr = np.random.rand(10,10)
max_pos = np.argmax(arr, axis=1)
print(max_pos)

25. 花式索引提取子矩阵

arr = np.random.randint(0,10,size=(3,4))
result = arr[[0,2]][:, [1,3]]   # 先取行,再取列
# 或者用 np.ix_: result = arr[np.ix_([0,2],[1,3])]
print(result)

26. 重塑为 2x3

a = np.arange(6).reshape(1,6)
b = a.reshape(2,3)
print(b)

27. 展平三维数组

arr = np.random.rand(2,3,4)
flat = arr.flatten()   # 或 arr.ravel()
print(flat.shape)

28. 广播求和

a = np.array([[1],[2],[3]])   # 形状(3,1)
b = np.array([[1,2,3,4]])     # 形状(1,4)
c = a + b                      # 广播后形状(3,4)
print(c)

29. 变形状再转置

a = np.arange(10)
a_2x5 = a.reshape(2,5)
a_T = a_2x5.T
print(a_T)

30. 垂直堆叠两行

arr = np.random.randint(0,10,size=(5,5))
stacked = np.vstack((arr[1,:], arr[2,:]))
print(stacked)

31. 水平拼接两个数组

A = np.random.randint(0,10,(3,3))
B = np.random.randint(0,10,(3,3))
C = np.hstack((A,B))
print(C.shape)

32. 变成列向量和行向量

a = np.array([1,2,3])
col = a[:, np.newaxis]   # 形状(3,1)
row = a[np.newaxis, :]   # 形状(1,3)
print(col.shape, row.shape)

33. resize 变为 2x8

arr = np.arange(16).reshape(4,4)
arr_resized = np.resize(arr, (2,8))   # resize 会重复填充
print(arr_resized)

34. 外积

a = np.array([1,2,3,4,5])
b = np.array([2,3,4])
outer = a[:, np.newaxis] * b[np.newaxis, :]
print(outer)

35. 每行减去行平均值

arr = np.random.randint(0,10,(3,3))
row_means = arr.mean(axis=1, keepdims=True)  # 保持维度以便广播
centered = arr - row_means
print(centered)

36. 均值、标准差、方差

arr = np.random.randint(0,100,(4,4))
mean = np.mean(arr)
std = np.std(arr)
var = np.var(arr)
print(mean, std, var)

37. 每列和、每行最大值

col_sum = np.sum(arr, axis=0)
row_max = np.max(arr, axis=1)
print(col_sum, row_max)

38. 对角线元素和

arr = np.random.randint(0,10,(5,5))
trace = np.trace(arr)
print(trace)

39. 矩阵乘积

A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
C = np.dot(A, B)   # 或 A @ B
print(C)

40. 求逆矩阵

A = np.random.rand(3,3)
A_inv = np.linalg.inv(A)
print(A_inv)

41. 解线性方程组

# x + 2y = 5, 3x + 4y = 6
A = np.array([[1,2],[3,4]])
b = np.array([5,6])
x = np.linalg.solve(A, b)
print(x)

42. 累积和

a = np.array([1,2,3,4])
cum = np.cumsum(a)
print(cum)

43. 全局最小值位置

arr = np.random.rand(10,10)
min_idx = np.unravel_index(np.argmin(arr), arr.shape)
print(min_idx)

44. 每行的极差

arr = np.random.randint(0,50,(3,4))
row_range = np.ptp(arr, axis=1)   # peak to peak
print(row_range)

45. 按列排序

arr = np.array([[3,1,2],[6,4,5]])
sorted_arr = np.sort(arr, axis=0)
print(sorted_arr)

46. 找出众数(频率最高的值)

arr = np.random.randint(0,10,1000)
values, counts = np.unique(arr, return_counts=True)
mode = values[np.argmax(counts)]
print(mode)

47. 移动平均

def moving_average(a, k=3):
    ret = np.cumsum(a, dtype=float)
    ret[k:] = ret[k:] - ret[:-k]
    ret[:k-1] = np.nan
    ret[k-1:] = ret[k-1:] / k
    return ret

a = np.arange(10)
print(moving_average(a, 3))

48. 大于 0.5 替换为 NaN,并计算剩余均值

arr = np.random.rand(20,20)
arr[arr > 0.5] = np.nan
mean_without_nan = np.nanmean(arr)
print(mean_without_nan)

49. 特征值和特征向量

arr = np.random.randint(1,10,(5,5))
eigenvalues, eigenvectors = np.linalg.eig(arr)
print(eigenvalues)
print(eigenvectors)

50. 两枚骰子点数之和分布

results = np.random.randint(1,7,size=(1000,2))  # 1000次,每次两枚
sums = results.sum(axis=1)
unique, counts = np.unique(sums, return_counts=True)
most_common_sum = unique[np.argmax(counts)]
print("最可能出现的和:", most_common_sum)

# 可选:绘制直方图(需 matplotlib)
import matplotlib.pyplot as plt
plt.hist(sums, bins=range(2,14), align='left', rwidth=0.8)
plt.show()
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐