NumPy: 创建数组
创建数组
1. 你将学到
❶ 从 Python 对象创建 ❷ 数值序列(arange / linspace / logspace) ❸ 预填充数组(zeros / ones / eye / full) ❹ 随机数创建 ❺ 从文件读取
2. 故事
Charlie 需要生成 0~2π 的 100 个等间距角度值。Python 循环 5 行,np.linspace 1 行:
linspace(0, 2*pi, 100)就是"从 0 到 2π 均匀取 100 个点"——代码即文档。
3. 知识点
(1) 从 Python 对象创建
最基础的方式——把 Python 列表(或嵌套列表)转为 NumPy 数组:
import numpy as np
a = np.array([1, 2, 3]) # 1D from list
b = np.array([[1, 2], [3, 4]]) # 2D from nested list
c = np.array([1, 2, 3], dtype=float) # specify dtype
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
创建方式对比
| 方式 | 语法 | 输入来源 | 典型用途 |
|---|---|---|---|
np.array |
np.array(obj) |
Python list/tuple | 从已有数据转换 |
np.arange |
np.arange(start, stop, step) |
数值范围 | 等差整数/浮点序列 |
np.linspace |
np.linspace(a, b, n) |
起止+点数 | 精确控制元素个数 |
np.zeros |
np.zeros(shape) |
形状 | 初始化全零 |
np.ones |
np.ones(shape) |
形状 | 初始化全一 |
np.full |
np.full(shape, val) |
形状+填充值 | 初始化为任意值 |
np.random.rand |
np.random.rand(n) |
元素个数 | 随机初始化 |
np.fromfunction |
np.fromfunction(fn, shape) |
函数+形状 | 按公式生成 |
(2) 数值序列
arange
np.arange(5) # [0 1 2 3 4]
np.arange(1, 10, 2) # [1 3 5 7 9]
np.arange(0, 1, 0.3) # [0. 0.3 0.6 0.9]
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
linspace
np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
np.linspace(0, 2*np.pi, 100) # 100 points from 0 to 2pi
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
logspace
np.logspace(1, 3, 3) # [ 10. 100. 1000.] -- 10^1, 10^2, 10^3
np.logspace(0, 2, 5) # 5 points from 10^0 to 10^2
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
arange vs linspace vs logspace
| 特性 | arange |
linspace |
logspace |
|---|---|---|---|
| 控制参数 | start, stop, step | start, stop, num | start_exp, stop_exp, num |
| 是否包含 stop | 不包含 | 包含 | 包含 |
| 间距类型 | 等差 | 等差 | 等比(指数等差) |
| 浮点精度 | 可能有误差 | 精确 | 精确 |
| 典型场景 | 整数索引 | 绘图采样 | 频率/对数刻度 |
(3) 预填充数组
np.zeros(3) # [0. 0. 0.]
np.zeros((2, 3)) # 2x3 zero matrix
np.ones((2, 2)) # 2x2 ones
np.eye(3) # 3x3 identity
np.full((2, 3), 7) # 2x3 filled with 7
np.empty((2, 2)) # 2x2 uninitialized (NOT zeros!)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
zeros vs empty vs full
| 函数 | 初始值 | 速度 | 安全性 | 用途 |
|---|---|---|---|---|
zeros |
全零 | 中 | 安全 | 需要确定初始值 |
empty |
未定义 | 快 | 不安全 | 即刻覆盖所有元素时 |
full |
自定义 | 中 | 安全 | 需要非零初始值 |
(4) 随机数创建
np.random.rand(3) # 3 uniform [0, 1)
np.random.rand(2, 3) # 2x3 uniform
np.random.randn(3) # 3 standard normal
np.random.randint(0, 10, 5) # 5 ints in [0, 10)
np.random.seed(42) # set seed for reproducibility
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
随机函数速查
| 函数 | 分布 | 范围 | 返回类型 |
|---|---|---|---|
rand(d0, d1, …) |
均匀 | [0, 1) | float |
randn(d0, d1, …) |
标准正态 | (-∞, +∞) | float |
randint(low, high, size) |
均匀整数 | [low, high) | int |
uniform(low, high, size) |
均匀 | [low, high) | float |
normal(loc, scale, size) |
正态 | (-∞, +∞) | float |
choice(a, size) |
离散均匀 | a 中的元素 | depends |
(5) 从文件读取
data = np.loadtxt('data.txt') # plain text
data = np.loadtxt('data.csv', delimiter=',') # CSV
data = np.genfromtxt('data.csv', delimiter=',', # handle missing
filling_values=0)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
fromfunction 简介——按坐标函数生成:
np.fromfunction(lambda i, j: i + j, (3, 3))
# [[0. 1. 2.]
# [1. 2. 3.]
# [2. 3. 4.]]
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:arange 与 linspace 生成序列(难度⭐)
import numpy as np
# arange: step-based
a = np.arange(0, 10, 2) # [0 2 4 6 8]
print("arange:", a)
# linspace: num-based
b = np.linspace(0, 10, 6) # 6 points: 0, 2, 4, 6, 8, 10
print("linspace:", b)
# logspace: logarithmic
c = np.logspace(1, 4, 4) # [10, 100, 1000, 10000]
print("logspace:", c)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:zeros / ones / eye / full 预填充(难度⭐)
import numpy as np
z = np.zeros((2, 3))
print("zeros:\n", z)
o = np.ones((3, 2))
print("ones:\n", o)
e = np.eye(4)
print("eye:\n", e)
f = np.full((2, 3), 9.0)
print("full:\n", f)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:嵌套列表创建 2D 数组(难度⭐)
import numpy as np
data = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
a = np.array(data)
print("shape:", a.shape) # (3, 3)
print("dtype:", a.dtype) # int64
print("ndim:", a.ndim) # 2
print("array:\n", a)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:fromfunction 按公式生成(难度⭐⭐)
import numpy as np
# multiplication table
mult = np.fromfunction(lambda i, j: (i+1) * (j+1), (9, 9), dtype=int)
print("9x9 table:\n", mult)
# checkerboard pattern
checker = np.fromfunction(lambda i, j: (i + j) % 2, (8, 8), dtype=int)
print("checkerboard:\n", checker)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:随机数生成(难度⭐⭐)
import numpy as np
np.random.seed(42)
# uniform random
u = np.random.rand(3, 3)
print("uniform:\n", u)
# standard normal
n = np.random.randn(3, 3)
print("normal:\n", n)
# random integers
ri = np.random.randint(1, 100, (3, 3))
print("randint:\n", ri)
# random choice
names = ['Alice', 'Bob', 'Charlie', 'Carol']
picked = np.random.choice(names, size=6)
print("choice:", picked)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
▶ 示例
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
:从文件读取数组(难度⭐⭐)
import numpy as np
import io
# simulate a CSV file
csv_data = "1.0,2.0,3.0\n4.0,5.0,6.0\n7.0,8.0,9.0"
data = np.loadtxt(io.StringIO(csv_data), delimiter=',')
print("loadtxt:\n", data)
# with missing values
csv_missing = "1.0,2.0,3.0\n4.0,,6.0\n7.0,8.0,9.0"
data2 = np.genfromtxt(io.StringIO(csv_missing), delimiter=',',
filling_values=-999)
print("genfromtxt:\n", data2)
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(6) 数组创建决策树
graph TB
A[Need to create array] --> B{Data source?}
B -->|Existing data| C[np.array from list/tuple]
B -->|Numeric range| D{Control parameter?}
D -->|Step size| E[np.arange]
D -->|Number of points| F{Spacing type?}
F -->|Linear| G[np.linspace]
F -->|Logarithmic| H[np.logspace]
B -->|Pre-filled| I{Fill value?}
I -->|All zeros| J[np.zeros]
I -->|All ones| K[np.ones]
I -->|Identity| L[np.eye]
I -->|Custom value| M[np.full]
B -->|Random| N{Distribution?}
N -->|Uniform 0-1| O[np.random.rand]
N -->|Normal| P[np.random.randn]
N -->|Integers| Q[np.random.randint]
B -->|Formula| R[np.fromfunction]
B -->|File| S[np.loadtxt/genfromtxt]
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
(7) ▶ 综合示例:5 种方式创建同一 3×3 数组 + 正弦曲线(难度⭐⭐⭐)
import numpy as np
# === 5 ways to create the same 3x3 array [[1,2,3],[4,5,6],[7,8,9]] ===
# Method 1: from list
a1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
# Method 2: arange + reshape
a2 = np.arange(1, 10).reshape(3, 3)
# Method 3: fromfunction
a3 = np.fromfunction(lambda i, j: i*3 + j + 1, (3, 3), dtype=int)
# Method 4: zeros + fill
a4 = np.zeros((3, 3), dtype=int)
for i in range(3):
for j in range(3):
a4[i, j] = i*3 + j + 1
# Method 5: full + arithmetic
a5 = np.full((3, 3), 0, dtype=int)
a5[:] = np.arange(1, 10).reshape(3, 3)
print("All equal?",
np.array_equal(a1, a2) and
np.array_equal(a2, a3) and
np.array_equal(a3, a4) and
np.array_equal(a4, a5))
# === Sine curve data with linspace ===
x = np.linspace(-np.pi, np.pi, 200)
y_sin = np.sin(x)
y_cos = np.cos(x)
print("x range: [{:.4f}, {:.4f}]".format(x[0], x[-1]))
print("sin samples:", len(y_sin))
print("cos samples:", len(y_cos))
> **输出:** 在本地 Python 环境运行 NumPy 2.x,输出 ndarray 数组内容。Piston 服务器未预装 NumPy,请在本机安装(`pip install numpy`)后实操对照。实际数值可能因 NumPy 版本、随机种子略有差异。
❓ 常见问题
np.empty 的"empty"指"未初始化"而非"空数组"。它分配内存但不赋值,内容是内存中的残留数据。仅在你立刻覆盖所有元素时用它来获得微小性能优势,否则应使用 zeros 确保安全。np.eye(N) 可生成 N×M 矩阵(支持非方阵)并指定对角线偏移(k 参数),np.identity(N) 只能生成 N×N 单位矩阵。功能上 identity(n) 等价于 eye(n),但 eye 更灵活。np.random.seed(42) 设置随机种子,同一种子产生相同序列。新版推荐使用 rng = np.random.default_rng(42) 创建 Generator 对象,线程更安全。fromfunction 对每个坐标调用一次函数,shape 较小时简洁方便;大规模数组(如 10,000×10,000)下,向量化运算(广播机制)更高效。fromfunction 适合表达公式,不适合性能瓶颈场景。linspace 替代。例如 np.arange(0, 1, 0.1) 可能产生 10 或 11 个元素(浮点误差),而 np.linspace(0, 1, 11) 精确生成 11 个点。📖 小节
NumPy 提供了丰富的数组创建方式,可按数据来源分为五大类:
- 从 Python 对象 —
np.array,关键词:转换、dtype - 数值序列 —
arange/linspace/logspace,关键词:步长、点数、对数 - 预填充 —
zeros/ones/eye/full/empty,关键词:零、一、单位、自定义 - 随机数 —
rand/randn/randint/normal,关键词:均匀、正态、整数 - 文件/函数 —
loadtxt/fromfunction,关键词:读取、公式
核心原则:优先选择语义最明确的创建方式——需要 100 个点就用 linspace,需要零矩阵就用 zeros,让代码自文档化。
📝 作业
- 基础题(难度⭐):3 种方式创建 5×5 全 1 矩阵
用 np.ones、np.full、np.eye + 算术 三种方式分别创建元素全为 1 的 5×5 数组,并用 np.array_equal 验证三者一致。
- 进阶题(难度⭐⭐):生成 -π~π 的 200 点并计算 sin/cos
用 linspace 生成从 -π 到 π 的 200 个等间距点,计算对应的 sin 和 cos 值,打印 sin 的最大值与 cos 的最小值。
- 挑战题(难度⭐⭐⭐):创建对角矩阵
分别用 np.diag、np.eye、np.zeros + 切片赋值 三种方式创建对角线元素为 [5, 10, 15, 20] 的 4×4 对角矩阵。