数据怎么进到程序里
这一章讲三件事:
f.read()里那个点号到底是什么; 几千张图和它们的标签在程序里该长什么样; 以及从一个压缩包到「训练集 / 验证集」两个清单,中间要走哪四步。 它在全书链条里的位置是第 2 级台阶: 能指挥计算机了,接下来得把数据喂进去。 遇到的 生词都在当场解释。
1. 顶层全景
硬盘上:Vehicle_Data.zip ← 300 张车辆图片,压在一个包里
│
│ ① 解压
▼
一堆文件夹,文件夹名就是类别名(car / truck / …)
│
│ ② 遍历,从文件夹名提出标签
▼
内存里:一串「文件路径 → 标签」
│
│ ③ 打乱
▼
同一串,但顺序被彻底搅过
│
│ ④ 按 9:1 切开
▼
train.txt(270 条) eval.txt(30 条)
│
▼
后面第 09 章起,每个项目都从这两个文件开始
图说:这四步是全书每一个项目的固定前奏,书自己也是这么说的。
这一章的主走查就是它——第 8 节从头走一遍。
在走这四步之前,要先把三样东西讲清楚:点号是什么(第 2 节)、 内存里那一串该用什么装(第 3—5 节)、怎么把文件里的东西读进内存(第 6 节)。
2. 先解决一个符号:f.read() 里那个点是什么
这一节只有一个概念,但你从下一节开始每一页都会看到它。
先看现象
你会在这本书后面看到大量这种写法:
f.read(5) # 从文件里读 5 个字符
img.convert("L") # 把图片转成灰度
"20230801.jpg".split(".") # 把文件名按点号切开
共同点是:一个东西,一个点,一个命令。 这个写法是什么意思?
做法:Python 里几乎所有东西都是「对象」
书在讲字符串的时候顺手交代了这件事:在 Python 解释器内部,
所有数据类型都是用面向对象方式实现的,封装为一个类;
字符串同样是一个类,有自己的方法,用的时候采用 <a>.<b> 的形式1。
翻译成人话:
一个对象 = 一份数据 + 一组只对这份数据有效的操作。 点号左边是那份数据,右边是你对它下的命令。
书还给了这两部分各自的名字2:
| 部分 | 名字 | 例子 |
|---|---|---|
| 那份数据 | 属性 | 一张图片的宽、高、格式 |
| 那些操作 | 方法 | 「把自己转成灰度」「把自己存到磁盘上」 |
img ──▶ 是一个对象,里面装着:
属性: size = (640, 480) format = "JPEG"
方法: convert() resize() save() show()
img.size ← 取它的一个属性,得到 (640, 480)
img.convert("L")← 让它执行一个方法,得到一张新的灰度图
图说:点号的意思永远是「这个东西的……」。
后面不再解释这个符号。
为什么在这里讲、而不是等到第 05 章: 因为本章和第 04 章通篇都在调方法, 而**「怎么自己写一个类」是另一回事,那个留给第 05 章。** 现在你只需要会用别人给你的对象。
3. 一个变量装一个值,为什么不够用
这一节从书自己的开头起手 —— 它的问题设置很好。
先看现象
书一上来给了三个真实问题3:
- 给定一组标签
{car, truck, bus, pedestrian, bicycle},统计每类各有多少张; - 给定一段行驶数据,统计其中「加速」状态占多大比例;
- 车载摄像头一次采集多张图,要批量分析。
拿第一个来看,有两种写法:
# 写法一:一个标签一个变量
a1 = 0 # car
a2 = 0 # truck
a3 = 0 # bus
a4 = 0 # pedestrian
a5 = 0 # bicycle
# 写法二:一个结构装一组,用序号区分
a = [0, 0, 0, 0, 0] # a[0] 是 car,a[1] 是 truck,……
看起来只是写法差别,其实是能不能扩展的差别:
| 写法一 | 写法二 | |
|---|---|---|
| 五个标签 | 能写 | 能写 |
| 一百个标签 | 要敲一百行 | 一行不变 |
| 想「每个标签都加一」 | 要敲五句 | 一个循环就完了 |
| 标签数量运行时才知道 | 做不到 | 照样能做 |
书的结论很直白:第二种方案「既可以减少程序中的变量数量,又便于程序循环遍历」4。 而第 01 章那 16000 张图,只有第二种写法扩得上去。
三类容器,按「数据之间是什么关系」分
Python 把这类「一次装一组」的东西叫组合数据类型,分成三类5:
| 类 | 关系 | 长什么样 | 什么时候用 |
|---|---|---|---|
| 序列 | 有先后顺序,可以重复 | [3, 1, 3]、(3, 1, 3)、"313" | 一批按顺序排开的东西 |
| 集合 | 没有顺序,不许重复 | {3, 1} | 只关心「有没有」「有哪些不重复的」 |
| 映射 | 一个键配一个值 | {"001.jpg": 0.5} | 「按名字查东西」 |
记住这张表的判据:先问「这组数据之间是什么关系」,再选容器。