【机器学习学习笔记】numpy基础
零基础入门 NumPy:从概念到实操整理
如果你想用电竞 Python 做 "算账"" 数据分析 " 这类和数字打交道的事,那NumPy绝对是绕不开的 "神器"。它就像给 Python 装了一个 "超级计算器",能轻松处理大堆数字、复杂表格(甚至更高维度的数字集合),而且速度比 Python 自带的工具快得多。下面用最通俗的语言,把 NumPy 的核心知识拆成 "能看懂、能上手" 的模块。
一、先搞懂:NumPy 到底是什么?为什么要用它?
1. NumPy 的定位
- 全称:Numerical Python(Python 的数值计算库)
- 核心作用:解决 Python 自带工具 "处理数字能力弱" 的问题 —— 比如 Python 自带的列表、元组只能处理 1 行数字(1 维),而 NumPy 能处理 "多行多列"(2 维)、"多层多行多列"(3 维)甚至更高维度的数字集合,还能快速做加减乘除、矩阵运算等。
- 隐藏身份:很多数据分析工具(比如 Pandas 表格、Matplotlib 画图)的 "底层发动机"—— 你装这些工具时,会自动装上 NumPy,因为它们需要靠 NumPy 算数据。
2. 对比:NumPy vs Python 自带工具
Python 自带 3 种 "存数字" 的方式,但都有局限:
类型 | 样子举例 | 缺点 |
---|---|---|
列表(list) | [1, 2, 3] | 只能 1 维,算数据慢 |
元组(tuple) | (1, 2, 3) | 只能 1 维,还不能改里面的数字 |
字典(dict) | {"A":1, "B":2} | 靠 "键值对" 存,不适合纯数字计算 |
而 NumPy 的核心 ——ndarray 多维数组,完美解决这些问题:
- 能存 1 维(像数轴)、2 维(像 Excel 表格)、3 维(像多层 Excel)...
- 算数据快 10~100 倍(底层用 C 语言写的)
- 支持各种数学运算(加减乘除、平方、开根号等)
二、基础中的基础:NumPy 的数据类型
Python 自带的数字类型只有 4 种(整数 int、小数 float、布尔 bool、复数 complex),但 NumPy 把它们拆得更细,能精准控制数字的 "大小" 和 "精度"(比如同样是整数,能分 "占 1 个字节的小整数" 和 "占 8 个字节的大整数"),避免浪费内存。
常用数据类型整理(记重点即可)
类型大类 | 具体类型 | 通俗解释 | 适用场景 |
---|---|---|---|
布尔型 | bool | 只有 True(真)/False(假),占 1 字节 | 判断条件(比如 "数字是否大于 5") |
整数型 | int8 /int32 /int64 | 不同大小的整数(8/32/64 表示占多少位) | 存年龄、数量等整数(数字小用 int8,大则用 int64) |
无符号整数型 | uint8 /uint64 | 只能存正数的整数(范围比普通整数大) | 存像素值(0~255)这类非负整数 |
浮点型(小数) | float32 /float64 | 不同精度的小数(64 比 32 精度更高) | 存身高(1.75 米)、体重(60.5kg)等小数,优先用 float64 |
复数型 | complex64 /complex128 | 数学中的复数(比如 1+2j) | 信号处理、量子计算等专业场景(小白暂时用不上) |
怎么指定 / 转换数据类型?
用 NumPy 创建数组时,可通过dtype
参数指定类型;创建后也能通过astype()
转换:
import numpy as np # 第一步:导入NumPy(约定俗成叫np)# 1. 创建数组时指定类型为float64(高精度小数)
a = np.array([1.1, 2.2, 3.3], dtype=np.float64)
print(a) # 输出:[1.1 2.2 3.3]
print(a.dtype) # 查看类型:float64# 2. 把小数转成整数(会丢掉小数部分,不是四舍五入!)
b = a.astype(np.int64)
print(b) # 输出:[1 2 3]
print(b.dtype) # 查看类型:int64
三、核心技能:创建 NumPy 数组(ndarray)
NumPy 提供了很多方法创建数组,不用死记硬背,先掌握最常用的 5 种:
1. 从 Python 列表 / 元组转过来(最基础)
用np.array()
把 Python 的列表或元组 "包装" 成 NumPy 数组,支持 1 维、2 维、3 维:
# 1维数组(像一条线)
arr1 = np.array([1, 2, 3, 4]) # 列表转1维
# 2维数组(像一张表格,几行几列)
arr2 = np.array([[1, 2, 3], [4, 5, 6]]) # 列表套列表转2维(2行3列)
# 3维数组(像一叠表格,几层几行几列)
arr3 = np.array([[[1,2],[3,4]], [[5,6],[7,8]]]) # 列表套列表套列表转3维(2层2行2列)# 查看数组形状(几行几列/几层):用.shape属性
print(arr1.shape) # (4,) → 1维,4个元素
print(arr2.shape) # (2, 3) → 2维,2行3列
print(arr3.shape) # (2, 2, 2) → 3维,2层2行2列
2. 创建 "有规律的数组"(最常用)
不用手动写列表,直接让 NumPy 生成固定规律的数组,比如 "从 3 到 7,每 0.5 一个数"、"全是 0 的数组":
方法 | 作用 | 例子(代码 + 输出) |
---|---|---|
np.arange() | 按 "起始 - 结束 - 步长" 生成数组(半开区间:包含起始,不包含结束) | np.arange(3, 7, 0.5) → [3. 3.5 4. 4.5 5. 5.5 6. 6.5] |
np.linspace() | 按 "起始 - 结束 - 个数" 生成均匀间隔的数组(默认包含结束) | np.linspace(0, 10, 5) → [ 0. 2.5 5. 7.5 10. ] |
np.ones() | 生成全是 1 的数组(需要指定形状) | np.ones((2, 3)) → [[1. 1. 1.],[1. 1. 1.]](2 行 3 列) |
np.zeros() | 生成全是 0 的数组(和 ones 用法一样) | np.zeros((3, 2)) → [[0. 0.],[0. 0.],[0. 0.]](3 行 2 列) |
np.eye() | 生成 "对角线上是 1,其余是 0" 的数组(矩阵) | np.eye(3) → [[1. 0. 0.],[0. 1. 0.],[0. 0. 1.]](3 行 3 列) |
3. 从函数 / 文件生成(进阶)
如果需要更灵活的数组(比如 "每个元素是行号 + 列号"),或从 Excel/Csv 文件读数据,可以用这些方法:
np.fromfunction()
:按函数规则生成数组# 生成2行3列的数组,每个元素=行号+列号(a是行号,b是列号) arr = np.fromfunction(lambda a, b: a + b, (2, 3)) print(arr) # 输出:[[0. 1. 2.],[1. 2. 3.]]
- 从文件读数据:后续学 Pandas 会更方便,NumPy 也有
np.fromfile()
,但需要先了解文件格式,小白暂时可跳过。
4. 生成随机数数组(常用在模拟 / 测试)
用np.random
模块生成随机数,比如 "10 个 2 到 5 之间的整数"、"符合正态分布的小数":
方法 | 作用 | 例子(代码 + 输出) |
---|---|---|
np.random.rand() | 生成 [0,1) 之间的均匀分布小数(指定形状) | np.random.rand(2,3) → [[0.2 0.5 0.8],[0.1 0.3 0.7]](2 行 3 列) |
np.random.randn() | 生成 "标准正态分布" 的小数(均值 0,标准差 1) | np.random.randn(1,5) → [[-0.2 0.8 -1.1 0.3 -0.5]] |
np.random.randint() | 生成 [low, high) 之间的随机整数 | np.random.randint(2, 5, 10) → [2 3 4 3 2 4 3 2 4 3](10 个整数) |
np.random.choice() | 从指定数组里随机抽数 | np.random.choice([1,3,5,7], 3) → [3 7 1](从 [1,3,5,7] 抽 3 个) |
四、必学操作:数组的 "花式变形"
创建数组后,经常需要调整它的形状(比如把 1 维数组改成 2 维)、合并 / 拆分数组等,这些操作是后续数据分析的基础。
1. 改变形状:reshape()
(不改变原数组)
把数组改成指定的形状,前提是 "总元素数不变"(比如 10 个元素可以改成 2 行 5 列,不能改成 3 行 4 列,因为 3×4=12≠10):
# 先创建1个1维数组(10个元素)
arr = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]# 改成2行5列的2维数组
arr2 = arr.reshape((2, 5))
print(arr2)
# 输出:
# [[0 1 2 3 4]
# [5 6 7 8 9]]# 查看原数组:没变化(reshape不修改原数组)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
2. 数组展平:ravel()
(把任意维数改成 1 维)
把 2 维、3 维数组 "压平" 成 1 维,方便后续处理:
arr = np.arange(10).reshape((2,5)) # 2行5列的数组# 按"行"展平(默认,先读第一行,再读第二行)
flat1 = np.ravel(arr)
print(flat1) # [0 1 2 3 4 5 6 7 8 9]# 按"列"展平(先读第一列,再读第二列)
flat2 = np.ravel(arr, order='F')
print(flat2) # [0 5 1 6 2 7 3 8 4 9]
3. 合并数组:concatenate()
(按指定方向拼)
把多个数组按 "行方向"(上下拼)或 "列方向"(左右拼)合并,注意:合并方向的维度要一致(比如上下拼,列数必须相同;左右拼,行数必须相同):
# 准备两个数组(都是2列)
a = np.array([[1,2], [3,4]]) # 2行2列
b = np.array([[5,6], [7,8]]) # 2行2列# 1. 按行方向合并(上下拼,axis=0)
merge0 = np.concatenate((a, b), axis=0)
print(merge0)
# 输出:
# [[1 2]
# [3 4]
# [5 6]
# [7 8]](4行2列)# 2. 按列方向合并(左右拼,axis=1)
merge1 = np.concatenate((a, b), axis=1)
print(merge1)
# 输出:
# [[1 2 5 6]
# [3 4 7 8]](2行4列)
4. 拆分数组:split()
(按指定份数拆)
把一个数组按 "行" 或 "列" 拆成多个子数组,需要指定拆分成几份(或拆分的位置):
# 准备一个4行2列的数组
arr = np.arange(8).reshape((4,2)) # [[0 1],[2 3],[4 5],[6 7]]# 1. 按行拆成2份(每份2行)
split0 = np.split(arr, 2, axis=0)
print(split0) # 得到两个子数组:[array([[0,1],[2,3]]), array([[4,5],[6,7]])]# 2. 按列拆成2份(每份1列)
split1 = np.split(arr, 2, axis=1)
print(split1) # 得到两个子数组:[array([[0],[2],[4],[6]]), array([[1],[3],[5],[7]])]
5. 插入 / 删除元素:insert()
/delete()
在指定位置插入或删除行 / 列:
arr = np.arange(12).reshape((3,4)) # 3行4列:[[0,1,2,3],[4,5,6,7],[8,9,10,11]]# 1. 删除:沿列方向(axis=1)删除第3列(索引从0开始,2就是第3列)
del_arr = np.delete(arr, 2, axis=1)
print(del_arr)
# 输出:
# [[0 1 3]
# [4 5 7]
# [8 9 11]](3行3列,少了原第3列)# 2. 插入:沿行方向(axis=0)在第3行前插入1行[100,200,300,400]
insert_arr = np.insert(arr, 2, [100,200,300,400], axis=0)
print(insert_arr)
# 输出:
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [100 200 300 400]
# [ 8 9 10 11]](4行4列,多了插入的行)
五、关键属性:快速了解数组信息
创建数组后,用这些 "属性"(不用加括号,直接.属性名
)能快速查看数组的核心信息:
arr = np.array([[1,2,3], [4,5,6]], dtype=np.float64) # 2行3列的小数数组print(arr.dtype) # 数据类型:float64
print(arr.shape) # 形状:(2, 3)(2行3列)
print(arr.ndim) # 维度:2(2维数组)
print(arr.size) # 总元素数:6(2×3=6)
print(arr.itemsize)# 每个元素占多少字节:8(float64占8字节)
print(arr.nbytes) # 数组总字节数:48(6×8=48)