深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【Python 系列 第6讲】CSV读写:保存再读回价格表

本讲使用 Python 标准库 csv 完成价格记录的最小文件往返:先写出 CSV,再读回并恢复价格类型,帮助新手第一次打通内存数据与本地文件之间的实操闭环。

2026-04-26 智铨研究 阅读时长 7 分钟

目录

  1. 本节目标
  2. 为什么第 6 讲先练“保存再读回”
  3. 准备一组最小价格记录
  4. 四步完成最小 CSV 往返
  5. 导入csv并指定文件名
  6. 把价格记录写成 CSV 文件
  7. 再把文件读回来
  8. 把读回的价格类型转成数值
  9. 怎样判断这次 CSV 往返是成功的
  10. 文件确实生成了
  11. 读回来的条数和原始记录一致
  12. 第一条日期没有丢
  13. 价格已经恢复成浮点数
  14. 为什么读回来的数据和写出去时看起来不一样
  15. 为什么close读回来变成字符串了
  16. 为什么 Windows 下会多空行
  17. 为什么建议用DictReader
  18. 文件名能不能换成别的
  19. 哪些情况仍然算本讲完成
  20. 写成一个最小保存和读取函数
  21. 第 6 讲建立的是“数据不只存在内存里”的意识
  22. 完成标准
  23. 系列衔接
  24. 风险揭示与免责声明

Python · 入门短课

  1. 第 1 讲【Python 系列 第1讲】Python环境检查:先打印一组收盘价
  2. 第 2 讲【Python 系列 第2讲】列表和字典:装下价格与日期
  3. 第 3 讲【Python 系列 第3讲】for循环:批量计算日收益率
  4. 第 4 讲【Python 系列 第4讲】函数封装:写一个收益率计算器
  5. 第 5 讲【Python 系列 第5讲】条件判断:筛出上涨交易日
  6. 第 6 讲【Python 系列 第6讲】CSV读写:保存再读回价格表
  7. 第 7 讲【Python 系列 第7讲】异常处理:避开空值和除零
  8. 第 8 讲【Python 系列 第8讲】生成一份行情摘要

【Python 系列 第6讲】CSV读写:保存再读回价格表

1. 本节目标

第 6 讲把前几讲一直在内存里操作的小样本,第一次真正落到文件里。目标很明确:学会用标准库 csv 把价格表写到磁盘,再从磁盘读回来,确认数据结构没有丢。量化练习不可能永远只靠手写列表,迟早要和文件发生关系,所以这一步值得尽早练熟。

学完这一讲后,你可以直接完成下面几件事:

  1. csv.writer 把价格样本写成 CSV 文件。
  2. csv.DictReader 把它重新读回来。
  3. 核对读回的数据是否还能继续用于后续分析。

第 6 讲的重点不是文件系统知识,而是让你第一次打通“内存数据 <-> 本地文件”的最小闭环。

2. 为什么第 6 讲先练“保存再读回”

如果只在代码里临时定义列表和字典,你很容易误以为数据处理一直都会这么简单。真实工作里,数据通常来自文件,也经常需要把结果再写回文件。若你在入门阶段不尽早练这一步,后面一碰到“把结果保存下来”,就很容易卡住。

第 6 讲故意只用标准库 csv,原因很简单:

  1. 不需要安装任何依赖,延续 starter 系列的低门槛。
  2. CSV 结构足够直白,适合观察字段和行。
  3. 你可以明确看到“写出”和“读回”是不是一一对应。

3. 准备一组最小价格记录

records = [
    {'date': '2024-01-01', 'close': 12.34},
    {'date': '2024-01-02', 'close': 12.80},
    {'date': '2024-01-03', 'close': 12.65},
]

当前只保留 dateclose 两列,目的是把文件读写动作本身看清楚,不让额外字段把注意力分散掉。

4. 四步完成最小 CSV 往返

下面四步分别解决文件路径、写出结构、读回内容和类型恢复四个问题,按顺序做最不容易丢字段或读错类型。

5. 导入csv并指定文件名

import csv

file_path = 'prices_sample.csv'

本讲先用相对路径,这样文件就会直接生成在当前脚本所在目录,最容易找到。

6. 把价格记录写成 CSV 文件

with open(file_path, 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['date', 'close'])
    for record in records:
        writer.writerow([record['date'], record['close']])

这里有三个细节值得记住:

  1. newline='' 能避免 Windows 下多余空行。
  2. encoding='utf-8' 能让后面加中文列名或摘要时更稳。
  3. 先写表头,再写每一行数据,是最清楚的 CSV 起步方式。

7. 再把文件读回来

loaded_records = []

with open(file_path, 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        loaded_records.append(row)

print(loaded_records)

这一步故意使用 DictReader,因为读回来以后,每一行都会直接按列名组织成字典,比“按位置取第 0 列、第 1 列”更直观。

8. 把读回的价格类型转成数值

for row in loaded_records:
    row['close'] = float(row['close'])

print(loaded_records)

CSV 文件里的数据读回来时通常先是字符串。若你后面还要继续算收益率,这一步转回浮点数很有必要。

9. 怎样判断这次 CSV 往返是成功的

验证时重点看三件事:文件有没有真的落盘、读回来的条数对不对、价格能不能恢复成后面还能继续计算的数值类型。

10. 文件确实生成了

import os
assert os.path.exists(file_path)

11. 读回来的条数和原始记录一致

assert len(loaded_records) == len(records)

12. 第一条日期没有丢

assert loaded_records[0]['date'] == '2024-01-01'

13. 价格已经恢复成浮点数

assert isinstance(loaded_records[0]['close'], float)
assert loaded_records[0]['close'] == 12.34

只要这几项通过,就说明你已经把“写出文件”和“读回继续用”这个闭环打通了。

14. 为什么读回来的数据和写出去时看起来不一样

这一节最常见的疑惑都和“CSV 只是文本格式”有关。只要先接受这一点,很多现象都会更容易理解。

15. 为什么close读回来变成字符串了

因为 CSV 本身只是一种文本格式,不会自动替你保留 Python 里的数值类型。需要你在读回后手动转成 float

16. 为什么 Windows 下会多空行

通常是写文件时少了 newline=''。这个参数在 CSV 入门里很常用,最好从一开始就养成习惯。

17. 为什么建议用DictReader

因为它能直接按列名读取,结构更清楚。对 starter 系列来说,这比按索引读列更适合入门。

18. 文件名能不能换成别的

当然可以。本讲重点不是文件名,而是你要知道“写哪儿、读哪儿、读回后长什么样”。

19. 哪些情况仍然算本讲完成

  1. 你可以把文件名改成别的,只要写和读使用的是同一个路径。
  2. 当前不要求处理特别大的 CSV,小样本就够。
  3. 当前只保存 dateclose,不要求把收益率一起写进去。
  4. 若你读回后先只打印,不立刻转 float,也可以,但后面继续分析前一定要补上类型转换。

20. 写成一个最小保存和读取函数

import csv


def save_price_csv(records, file_path):
    with open(file_path, 'w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(['date', 'close'])
        for record in records:
            writer.writerow([record['date'], record['close']])


def load_price_csv(file_path):
    loaded = []
    with open(file_path, 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            row['close'] = float(row['close'])
            loaded.append(row)
    return loaded

这样你下一次换一组样本时,不用再从零重写整段文件操作。

21. 第 6 讲建立的是“数据不只存在内存里”的意识

前几讲的价格、收益率和筛选结果都只活在脚本运行当下。第 6 讲的价值,在于让你第一次明确感受到:一份小数据是可以被保存、被重新读取、被重复使用的。对量化入门来说,这一步非常重要,因为后面你几乎一定会处理外部文件。

因此,本讲真正跑通的,不只是 csv 的基本写法,而是“我写出来的数据,下一次还能读回来继续分析”的工作流意识。

22. 完成标准

如果你现在已经能把一组价格记录写成 CSV,再读回来并恢复成可继续计算的结构,那第 6 讲就算完成。

23. 系列衔接

本讲是《Python量化入门短课》的第 6/8 讲,当前主题是《CSV读写:保存再读回价格表》。

上一讲:第 5 讲《条件判断:筛出上涨交易日》。

下一讲:第 7 讲《异常处理:避开空值和除零》。

后续安排:第 8 讲《生成一份行情摘要》。

24. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。