Numpy-数据操作

前言

上一节我们理解了ndarray的核心概念(shape、dtype、strides、axis),本节课聚焦于如何操作数组中的数据。我们不可能每一个API都讲到,AI时代不再局限于API的记忆,需要有一个概念知道Numpy可以做什么,附带官网地址

数组创建

除了从列表直接创建,NumPy 提供了很多便捷的构造方法。

js 复制代码
print('zeros(2, 3):', np.zeros((2, 3)))
print('ones(2, 3):', np.ones((2, 3)))
print('full(2, 3, 7):', np.full((2, 3), 7))
print('eye(3):', np.eye(3))
js 复制代码
# np.arange: 创建等差数组
print('arange(0, 10, 2):', np.arange(0, 10, 2))
# np.linspace: 创建等间隔数组
print('linspace(0, 1, 5):', np.linspace(0, 1, 5))
# np.linspace: 创建等间隔数组
print('linspace(0, 1, 5, endpoint=False):', np.linspace(0, 1, 5, endpoint=False))
js 复制代码
# default_rng: 创建随机数生成器 
rng = np.random.default_rng(41) 
# uniform: 生成均匀分布随机数 
print('uniform(0, 1, (2,3)):\n', rng.uniform(0, 1, (2,3)), '\n') 
# normal: 生成正态分布随机数 
print('normal(0, 1, (2,3)):\n', rng.normal(0, 1, (2,3)), '\n') 
# integers: 生成随机整数 
print('integers(0, 10, (2,3)):\n', rng.integers(0, 10, (2,3)))

这里np.random.default_rng(41)的参数41代表参数seed,使用相同种子,每次运行会得到相同的随机数序列,便于复现实验。

索引与切片

NumPy 的索引语法与 Python 列表类似,但支持多维操作。

基本索引与切片

语法:arr[start:stop:step],多维就用逗号分隔。

  • start:起始索引,默认 0
  • stop:结束索引(不包含),默认数组长度
  • step:步长,默认 1

注意:切片返回的是视图(view),不是拷贝------改切片会影响原数组。

js 复制代码
# np.arange: 创建等差数组 
arr = np.arange(12).reshape(3, 4) 
print('原数组:\n', arr, '\n') 
print('arr[0]:', arr[0]) 
print('arr[:, 1]:\n', arr[:, 1:]) 
print('arr[1:, 2:]:\n', arr[1:, 2:])
lua 复制代码
原数组:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]] 

arr[0]: [0 1 2 3]
arr[:, 1]:
 [[ 1  2  3]
 [ 5  6  7]
 [ 9 10 11]]
arr[1:, 2:]:
 [[ 6  7]
 [10 11]]
js 复制代码
view = arr[1:, 2:] 
view[0, 0] = 99 
print('修改视图后原数组:\n', arr) 
# copy: 创建数组的副本 
copy = arr[1:, 2:].copy()
lua 复制代码
修改视图后原数组:
 [[ 0  1  2  3]
 [ 4  5 99  7]
 [ 8  9 10 11]]

花式索引(Fancy Indexing)

用整数数组选取不连续的行/列。返回的是拷贝。

js 复制代码
# np.arange: 创建等差数组 
arr = np.arange(12).reshape(4, 3) 
print('数组:\n', arr, '\n') 
print('arr[[0, 2]]:\n', arr[[0, 2]], '\n') 
rows = [0, 1, 3] 
cols = [2, 1, 0] 
print('arr[rows, cols]:', arr[rows, cols])
lua 复制代码
数组:
 [[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]] 

arr[[0, 2]]:
 [[0 1 2]
 [6 7 8]] 

arr[rows, cols]: [2 4 9]

这里面arr[rows, cols]可能大家不好理解,我们知道对于二维数组我们要取其中一个值是用arr[row, col],这里同样也是这个道理,只不过复数的情况下取出来的是个数组,拆解上面的语句arr[[0, 1, 3], [2, 1, 0]],可以理解依次取数组中0, 21, 13, 0这三个位置的数据,返回2, 4, 9

布尔索引(Boolean Indexing)

用布尔数组作为掩码(mask),选取满足条件的元素。返回的是拷贝。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([10, 25, 3, 47, 8, 19]) 
mask = arr > 15 
print('mask:', mask) 
print('arr[arr > 15]:', arr[mask])
print('arr[arr % 2 == 0]:', arr[arr % 2 == 0])
vbnet 复制代码
mask: [False  True False  True False  True]
arr[arr > 15]: [25 47 19]
arr[arr % 2 == 0]: [10  8]
js 复制代码
arr = np.array([5, 12, 18, 25, 30, 7, 42]) 
print('(>10) & (<30):', arr[(arr > 10) & (arr < 30)]) 
print('(<10) | (>30):', arr[(arr < 10) | (arr > 30)])
ini 复制代码
(>10) & (<30): [12 18 25]
(<10) | (>30): [ 5  7 42]

变形与重塑

改变数组的形状而不改数据。总元素数必须一致,用 -1 让 NumPy 自动算。

js 复制代码
# np.arange: 创建等差数组 
arr = np.arange(12) 
print('原始:', arr, '\n') 
# reshape: 重塑数组形状 
print('reshape(3, 4):\n', arr.reshape(3, 4), '\n') 
# reshape: 重塑数组形状 
print('reshape(2, -1):\n', arr.reshape(2, -1), '\n') 
# reshape: 重塑数组形状 
print('reshape(2, 2, 3):\n', arr.reshape(2, 2, 3))
lua 复制代码
原始: [ 0  1  2  3  4  5  6  7  8  9 10 11] 

reshape(3, 4):
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]] 

reshape(2, -1):
 [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]] 

reshape(2, 2, 3):
 [[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]
js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([1, 2, 3, 4]) 
# np.resize: 改变数组大小(可重复填充) 
print('np.resize(arr, (2, 3)):\n', np.resize(arr, (2, 3))) 
# np.resize: 改变数组大小(可重复填充) 
print('np.resize(arr, (2, 2)):\n', np.resize(arr, (2, 2)))
lua 复制代码
np.resize(arr, (2, 3)):
 [[1 2 3]
 [4 1 2]]
np.resize(arr, (2, 2)):
 [[1 2]
 [3 4]]

数学运算

NumPy 的所有运算符都是向量化的------对整个数组一次性操作,不用写循环。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([1, 2, 3, 4]) 
print('原数组:', arr) 
print('arr + 10:', arr + 10) 
print('arr * 2:', arr * 2) 
print('arr ** 2:', arr ** 2) 
print('arr > 2:', arr > 2)
yaml 复制代码
原数组: [1 2 3 4]
arr + 10: [11 12 13 14]
arr * 2: [2 4 6 8]
arr ** 2: [ 1  4  9 16]
arr > 2: [False False  True  True]
js 复制代码
# np.array: 从列表创建 NumPy 数组 
a = np.array([10, 20, 30]) 
# np.array: 从列表创建 NumPy 数组 
b = np.array([1, 2, 3]) 
print('a + b:', a + b) 
print('a - b:', a - b) 
print('a * b:', a * b) 
print('a / b:', a / b)
less 复制代码
a + b: [11 22 33]
a - b: [ 9 18 27]
a * b: [10 40 90]
a / b: [10. 10. 10.]

统计运算

对数组做聚合统计,可以用 axis 指定沿哪个方向算。

js 复制代码
# np.arange: 创建等差数组 
arr = np.arange(12).reshape(3, 4).astype(float) 
print('数组:\n', arr, '\n') 
# sum: 计算所有元素之和 
print('sum:', arr.sum()) 
# mean: 计算算术平均值 
print('mean:', arr.mean()) 
# sum: 计算所有元素之和 
print('sum(axis=0) 按列求和:', arr.sum(axis=0)) 
# sum: 计算所有元素之和 
print('sum(axis=1) 按行求和:', arr.sum(axis=1)) 
# min: 找出最小值 
print('min:', arr.min(), ', max:', arr.max()) 
# argmin: 找出最小值所在的索引 
print('argmin:', arr.argmin(), ', argmax:', arr.argmax())
ini 复制代码
数组:
 [[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]
 [ 8.  9. 10. 11.]] 

sum: 66.0
mean: 5.5
sum(axis=0) 按列求和: [12. 15. 18. 21.]
sum(axis=1) 按行求和: [ 6. 22. 38.]
min: 0.0 , max: 11.0
argmin: 0 , argmax: 11

标准差

标准差(Standard Deviation)是统计学中衡量数据波动程度(即离散程度)最常用的指标。简单来说,它告诉你数据围绕平均值有多"散"。

标准差越小:说明数据越集中,平均值越有代表性(大家成绩都差不多)。

标准差越大:说明数据越分散,平均值越不靠谱(有人考100分,有人考0分)。

js 复制代码
print("arr", arr) 
print("mean", arr.mean()) 
# std: 计算总体标准差 
print('std总体标准差:', arr.std()) 
# std: 计算样本标准差 
print('std(ddof=1)样本标准差:', arr.std(ddof=1)) 
# 变异系数 
print('变异系数CV:', arr.std() / arr.mean())
ini 复制代码
arr [[ 0.  1.  2.  3.]
 [ 4.  5.  6.  7.]
 [ 8.  9. 10. 11.]]
mean 5.5
std总体标准差: 3.452052529534663
std(ddof=1)样本标准差: 3.605551275463989
变异系数CV: 0.6276459144608478
CV 范围 离散程度 直观感受 典型场景举例
< 10% 非常小 数据极度集中,几乎一模一样 工厂自动化生产的零件尺寸、精密仪器读数
10% ~ 20% 较小 有波动但很稳定,平均值可靠 成年人的身高、体重、日常气温
20% ~ 30% 中等 正常波动范围,尚可接受 学生考试成绩、员工绩效评分
30% ~ 50% 较大 数据比较分散,平均值代表性下降 城市房价、不同地区的薪资水平
> 50% 非常大 极度分散,平均值几乎没意义 股票日收益率、创业公司估值、个人消费支出

条件筛选与 np.where

np.where(condition, x, y) ------ 如果条件成立取 x 的值,否则取 y 的值。类似向量化的 if-else。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([10, -5, 3, -8, 0, 15]) 
# np.where: 根据条件筛选或替换值 
result = np.where(arr < 0, 0, arr) 
print('原数组:', arr) 
print('负数变 0:', result)
ini 复制代码
原数组: [10 -5  3 -8  0 15]
负数变 0: [10  0  3  0  0 15]

拼接与分割

把多个数组合并,或把一个数组拆成多份。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
a = np.array([[1, 2], [3, 4]]) 
# np.array: 从列表创建 NumPy 数组 
b = np.array([[5, 6]]) 
# np.vstack: 垂直堆叠数组 
print('vstack (垂直拼):\n', np.vstack([a, b]), '\n') 
# np.concatenate: 沿指定轴拼接数组 
print('concatenate axis=0:\n', np.concatenate([a, b], axis=0))
lua 复制代码
vstack (垂直拼):
 [[1 2]
 [3 4]
 [5 6]] 

concatenate axis=0:
 [[1 2]
 [3 4]
 [5 6]]

排序

排序在很多场景中都会用到。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6]) 
print('原数组:', arr) 
# np.sort: 返回排序后的数组 
print('np.sort(arr):', np.sort(arr)) 
# np.argsort: 返回排序后的索引数组 
print('np.argsort(arr):', np.argsort(arr)) 
# np.unique: 返回唯一值 
print('np.unique(arr):', np.unique(arr))
ini 复制代码
原数组: [3 1 4 1 5 9 2 6]
np.sort(arr): [1 1 2 3 4 5 6 9]
np.argsort(arr): [1 3 6 0 2 4 7 5]
np.unique(arr): [1 2 3 4 5 6 9]

广播(Broadcasting)

广播是 NumPy 的特色:对不同形状的数组做运算时,NumPy 会自动把小数组「扩展」成和大数组一样的形状,无需手动复制。

规则:从尾部维度开始比,维度相同或有一个是 1 就能广播。

js 复制代码
# np.array: 从列表创建 NumPy 数组 
arr = np.array([1, 2, 3]) 
print('arr + 10:', arr + 10) 
print('arr * 5:', arr * 5)
ini 复制代码
arr + 10: [11 12 13]
arr * 5: [ 5 10 15]
js 复制代码
# np.arange: 创建等差数组 
matrix = np.arange(12).reshape(3, 4) 
# np.array: 从列表创建 NumPy 数组 
row = np.array([10, 20, 30, 40]) 
# np.array: 从列表创建 NumPy 数组 
col = np.array([[100], [200], [300]]) 
print('matrix:\n', matrix, '\n') 
print('matrix + row (行广播):\n', matrix + row, '\n') 
#reshape: 重塑数组形状 
print('matrix + col[:, None] (列广播):\n', matrix + col)

总结

本文只介绍了常规操作,大家应该能看出来Numpy更偏数学属性,与线性代数类似,不必纠结于API调用,理解它能为我们提供什么样的服务就可以。

相关推荐
Aloudata2 小时前
语义治理 vs 知识治理:AI 数据分析需要业务知识库还是可执行语义层
大数据·人工智能·数据分析·data agent·语义层
小白的后端世界2 小时前
数据分析基础学习
人工智能·学习·数据分析
quantdash_cc3 小时前
数据 API 的稳定性应该如何长期监控?从量化数据监控体系到 QuantDash 实践
开发语言·python·数据分析·量化交易·股票数据·quantdash
TKcloudmaster_H4 小时前
告别低效运营:跨境数据分析 + 多账号矩阵增效方案
大数据·矩阵·数据挖掘·数据分析·新媒体运营·产品运营·流量运营
涛思数据(TDengine)4 小时前
存储成本降低80%,Zendure用TDengine支撑117万台设备的能源数据分析
大数据·数据库·人工智能·数据分析·时序数据库·tdengine·工业
hqyjzsb13 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析
2601_9620780320 小时前
Python办公自动化与数据分析实战 培训班2021年
python·数据分析·办公自动化·自动化办公·实战演练
2601_9669496520 小时前
批量获取多只股票五档盘口的极简方案:QuantDash Python SDK 实战指南
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
SelectDB21 小时前
Apache Doris+ Paimon 2.0:构建 Agentic AI 数据闭环
大数据·数据库·数据分析