Python学习笔记·第18天:进入数据分析大门——NumPy核心基础
·
一、如何创建数组
NumPy 提供了多种创建数组的方法,最核心的是 np.array(),同时内置了许多快捷生成函数。
import numpy as np
# 1. 从列表、元组、range对象转换
np.array([1,2,3,4,5]) # 列表转数组
np.array((1,2,3,4,5)) # 元组转数组
np.array(range(5)) # range对象转数组
np.array([[1,2,3],[4,5,6]]) # 二维数组
# 2. 类似range的快捷生成
np.arange(8) # 类似range,返回数组 [0..7]
np.arange(1, 10, 2) # 起始1,结束10,步长2
# 3. 等差/等比/全零/全一数组
np.linspace(0, 10, 11) # 0到10之间生成11个等差元素
np.linspace(0, 10, 11, endpoint=False) # 不包含终点
np.logspace(0, 100, 10) # 等比数列,10的幂次
np.zeros(3) # 全0数组
np.ones(3) # 全1数组
np.identity(3) # 单位矩阵(3x3)
np.diag([1,2,3,4]) # 对角矩阵
# 4. 随机数数组
np.random.randint(0, 50, 5) # 0-50随机5个整数
np.random.randint(0, 50, (3,5))# 0-50随机数,形状3x5
np.random.rand(10) # 10个0-1均匀分布随机数
np.random.standard_normal(5) # 5个标准正态分布随机数
重点:
np.arange和内置range的区别在于,arange返回的是数组,支持更多数学运算。
二、修改数组中的元素
NumPy 中修改元素有两种本质区别:原地修改 vs 生成新数组。
x = np.arange(8)
# 追加元素(返回新数组,不改变原数组)
np.append(x, 8) # 末尾追加一个
np.append(x, [9,10]) # 末尾追加多个
# 原地修改(会改变原数组)
x[3] = 8 # 下标直接赋值
# 插入元素(返回新数组)
np.insert(x, 1, 8) # 在下标1处插入值8
# 二维数组的修改
x = np.array([[1,2,3],[4,5,6],[7,8,9]])
x[0, 2] = 4 # 修改第0行第2列
x[1:, 1:] = 1 # 切片批量修改:行≥1且列≥1的区域
x[1:, 1:] = [[1,2],[3,4]] # 同时修改多个值(注意形状匹配)
三、数组与常量的运算
数组与常量进行运算时,会逐个元素进行计算(广播机制)。
x = np.array((1,2,3,4,5))
# 数组在前,常量在后:数组的每个元素与常量运算
x * 2 # 每个元素乘以2
x / 2 # 每个元素除以2
x // 2 # 整除
x ** 3 # 每个元素的三次方
x + 2 # 每个元素加2
# 常量在前,数组在后:注意运算结果不同
2 ** x # 2的x次方(2^1, 2^2, 2^3...)
2 / x # 2除以每个元素
四、数组与数组的运算
# 等长数组:对应位置元素运算
np.array([1,2,3]) + np.array([4,3,2]) # 逐元素相加
# 不等长但可广播:短的数组会“扩展”
a = np.array([1,2,3])
b = np.array([[1,2,3], [4,5,6], [7,8,9]])
c = a * b # a的每个元素乘以b对应列的元素
a + b # a的每个元素加b对应列的元素
广播原则:如果两个数组维度不同,NumPy 会尝试将较小的数组“广播”到与大数组兼容的形状。如果无法广播,则报错。
五、数组的排序
x = np.array([3, 1, 2, 4])
# 返回排序后的下标数组(不改变原数组)
np.argsort(x) # 返回 [1, 2, 0, 3],对应 1->2->3->4
# 最大/最小值的下标
x.argmax() # 3(最大值4的下标)
x.argmin() # 1(最小值1的下标)
# 原地排序(改变原数组)
x.sort() # x 变为 [1, 2, 3, 4]
关键理解:
argsort()返回的是下标数组,可以通过x[_]取出排序后的原值。
六、数组的内积运算
内积 = 对应位置元素的乘积之和。
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
np.dot(x, y) # 32
x.dot(y) # 32
sum(x * y) # 32
# 计算:1*4 + 2*5 + 3*6 = 32
七、比较两个数组
判断两个数组中对应位置的元素是否足够接近:
x = np.array([1, 2, 3, 4.001, 5])
y = np.array([1, 1.999, 3, 4.01, 5.1])
np.allclose(x, y) # 逐个比较,全为True则True
np.allclose(x, y, rtol=0.2) # 设置相对误差
np.allclose(x, y, atol=0.2) # 设置绝对误差
np.isclose(x, y) # 返回布尔数组,每个位置独立比较
八、访问数组中的元素
b = np.array([[1,2,3],[4,5,6],[7,8,9]])
# 基础访问
b[0] # 第0行所有元素
b[0, 2] # 第0行第2列的元素
b[0][2] # 等价写法
# 列表索引(花式索引)
b[[0, 1]] # 第0行和第1行的所有元素
b[[0, 2, 1], [2, 1, 0]] # 分别取 (0,2), (2,1), (1,0) 三个位置的元素
# 切片访问
a = np.arange(10)
a[::-1] # 反向切片
a[::2] # 隔一个取一个
a[:5] # 前5个元素
九、修改数组形状
c = np.arange(25)
c.shape = 5, 5 # 变成5行5列的二维数组
# 切片组合访问
c[0, 2:5] # 第0行,列下标[2,5)的元素
c[2:5, 2:5] # 行和列同时切片,取子区域
c[:, 2] # 第2列所有元素(冒号代表所有行)
c[:, [2, 4]] # 第2列和第4列所有元素
c[[1, 3]] # 第1行和第3行所有元素
c[[1, 3]][:, [2, 4]] # 第1、3行的第2、4列元素
今日核心总结
-
数组创建:
np.array()是最核心的转换方式,掌握arange、linspace、zeros/ones、random等快捷生成函数。 -
运算原则:
- 数组与常量:逐元素运算,注意“数组在前”和“常量在前”的结果差异
- 数组与数组:等长直接算,不等长则广播(能广播则算,不能就报错)
-
排序诀窍:
argsort()返回的是下标数组,不是排序后的值argmax/argmin返回最大/最小值的下标sort()是原地排序,会改变原数组
-
访问与修改:
- 修改数组有“返回新数组”和“原地修改”两种方式,注意区分
- 花式索引(列表索引)可以同时取多个任意位置的元素
- 切片是视图,修改切片会影响原数组
-
形状变换:
shape属性直接修改形状;使用[:, 2]这样的语法切出特定行列。
注:已经使用DeepSeek进行整理精简核心内容,些许不理解的配合个人笔记进行理解。
更多推荐


所有评论(0)