AI编程(二十五):CSV文件入门 — 让表格数据流动起来

作者:

在

工资条、账单、通讯录、成绩表——程序世界和Excel世界的第一次握手

一、你的数据,大多锁在表格里

先想想你电脑里有多少表格文件:

  • 银行卡导出的账单(.csv 或 .xlsx)
  • 公司发的工资条
  • 通讯录导出的联系人列表
  • 上课时的成绩表、考勤表
  • 网店后台导出的订单明细

这些数据有个共同的尴尬:Excel能看,但没法”自动化”。想算点东西要手动拉公式,想整理几百行要拖到手酸,想每周重复做一遍——每周都得重来一次。

从今天起不一样了。我们开始爬阶段3的第一个台阶:文件和数据处理。第一站就是CSV——因为它是表格数据里最简单、最通用、最好上手的格式。

今天你只需要学会两件事:把CSV读进程序,把数据写回CSV。就这两招,已经够你做很多事了。

二、CSV是什么?一张”纯文本表格”

CSV全称 Comma-Separated Values,逗号分隔值。名字听着专业,其实朴素得不行——它就是个文本文件,每行一条记录,用逗号把一格一格的数据隔开。

用记事本打开一个CSV,长这样:

姓名,年龄,城市
张三,28,北京
李四,35,上海
王五,22,广州

而同样的内容用Excel打开,是一个规规矩矩的表格。

姓名 年龄 城市

|——|——|——|

张三 28 北京
李四 35 上海
王五 22 广州

看出来了吗?CSV就是”脱掉Excel外套的表格“。没有格式、没有公式、没有花里胡哨的颜色——只有数据本身。

这恰恰是它对程序友好的原因:程序不用学会Excel那套复杂格式,只要读懂”逗号隔开的文本”就行。这也是为什么几乎所有的软件——银行系统、网店后台、数据库——都支持导出CSV:它就是表格数据界的”普通话”。

三、读CSV:把表格搬进程序

Python自带一个csv模块,标准库里的,不用安装。

第一步:让AI给你写个”读取器”

跟AI说需求(记住这个姿势,整个阶段3都靠它):

我有一个CSV文件叫账单.csv,第一行是表头”日期,项目,金额”。帮我写个Python程序,把里面的内容一行行打印出来。

AI大概率会给你这样的代码:

import csv

with open("账单.csv", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

跑一下,输出类似:

['日期', '项目', '金额']
['10-01', '午饭', '25']
['10-02', '打车', '18.5']
['10-03', '书', '56']

三行代码,逐行拆解:

  • import csv——把Python自带的表格工具箱搬进来
  • open("账单.csv", encoding="utf-8")——打开文件。encoding="utf-8"先记住要写,一会儿讲为什么
  • csv.reader(f)——把文件变成一个”逐行读取器”
  • for row in reader——一行一行拿出来

注意看输出:每一行row都是一个列表。第一行是表头,后面是数据。就这么简单。

第二步:跳过表头,直接拿数据

大多数时候表头是给人看的,程序要的是数据。跳过它有好几种办法,最直观的是这样:

import csv

with open("账单.csv", encoding="utf-8") as f:
    reader = csv.reader(f)
    next(reader)  # 跳过第一行表头
    for row in reader:
        日期, 项目, 金额 = row  # 直接解包成三个变量
        print(f"{日期} 花了 {金额} 元买{项目}")

next(reader)的意思是”读一行然后扔掉”,正好用来跳表头。接下来日期, 项目, 金额 = row这一招你可能没见过——它叫解包:把列表里的三项按顺序装进三个变量。比用row[0]、row[1]可读多了。

第三步:DictReader——让每行数据自带”标签”

解包有个前提:你得记住第一列是日期、第二列是项目。列一多就乱了。

csv.DictReader更聪明:它直接拿表头当字典的键,每行数据都是一个字典:

import csv

with open("账单.csv", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["日期"], row["项目"], row["金额"])

每个row长这样:

{"日期": "10-01", "项目": "午饭", "金额": "25"}

用键名取值,不怕列顺序变。列再多也不乱。实际写程序,我推荐你优先用DictReader——第二十篇单位转换器里我们说过,字典就是”给数据贴标签”,DictReader把这招用在了表格上。

小提醒:DictReader读出来的值全是字符串。就算金额那一列写的是25,拿到手也是”25″。要算数,得先float(row["金额"])——这个坑我们第五节实战里会踩到。

四、写CSV:把程序的结果存成表格

读进来只是半场,把处理好的数据写回去才是完整闭环。

writer:一行一行写

import csv

# 要写入的数据
rows = [
    ["姓名", "部门", "工资"],
    ["张三", "技术部", "18000"],
    ["李四", "市场部", "15000"],
]

with open("工资表.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    for row in rows:
        writer.writerow(row)

跑完打开”工资表.csv”,就是一张干干净净的表格。

三个新面孔:

  • open(..., "w", ...)——w是”写模式”。注意:文件已存在会被整个覆盖,想保留旧内容用a(追加)
  • newline=""——Windows上不加它,表格会莫名多出空行。听医生的,加上
  • writer.writerow(row)——写一行。如果一次要写很多行,用writer.writerows(rows)更省事(注意是复数的rows,一次写一批)

DictWriter:带着标签写

读有DictReader,写有DictWriter,成对出现:

import csv

with open("工资表.csv", "w", encoding="utf-8", newline="") as f:
    字段 = ["姓名", "部门", "工资"]
    writer = csv.DictWriter(f, fieldnames=字段)
    writer.writeheader()  # 先写表头
    writer.writerow({"姓名": "张三", "部门": "技术部", "工资": "18000"})
    writer.writerow({"姓名": "李四", "部门": "市场部", "工资": "15000"})

fieldnames定义列的顺序,writeheader()写表头行,之后每行传字典就行。键名对不上会报错——这是好事,它在帮你抓笔误。

五、实战:账单整理小工具

学完读写,马上造个能用的东西。需求场景:银行导出的账单.csv又乱又长,你想知道”这个月花了多少钱、花在哪类项目上”。

跟AI说需求:

我有一个账单.csv,表头是”日期,项目,金额”,有几百行。帮我写个程序:读取所有数据,算出总金额,按项目分类汇总(比如”吃饭一共花了多少”),把汇总结果存成一个汇总.csv,两列:”项目,小计”。

拿到代码别直接跑完就扔,逐块读懂:

import csv

# 读取账单
明细 = []
with open("账单.csv", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        明细.append({
            "日期": row["日期"],
            "项目": row["项目"],
            "金额": float(row["金额"]),  # 字符串转数字!
        })

# 分类汇总
汇总 = {}
for item in 明细:
    项目 = item["项目"]
    汇总[项目] = 汇总.get(项目, 0) + item["金额"]

# 算总额
总额 = sum(item["金额"] for item in 明细)

# 写出汇总.csv
with open("汇总.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["项目", "小计"])
    for 项目, 小计 in 汇总.items():
        writer.writerow([项目, round(小计, 2)])

print(f"分析完成!总支出 {总额:.2f} 元,结果已存到 汇总.csv")

这个程序串起了你学过的所有东西:

  • 字典列表存明细(第十七篇成绩管理器的结构)
  • 字典做累加器汇总.get(项目, 0) + ...(第十五篇单词统计器的同款招式,只是统计的从单词换成了钱)
  • float()转换——第三节小提醒说的那个坑,就在这儿:CSV读出来是字符串,不转数字,+会变成字符串拼接,”25″+”18.5″变成”2518.5″,账就算错了
  • 读CSV进、写CSV出——今天的新知识,就这两下

跑完用Excel打开汇总.csv,一张清爽的分类账单。几百行的原始账单,一秒钟变结论——这就是数据处理的意义。

六、三个必踩的坑(先打疫苗)

坑1:Excel打开CSV是乱码

这是新手放弃率最高的坑。原因:Excel默认用GBK编码读CSV,而Python默认写UTF-8。两边说的不是一种”方言”,Excel就把中文显示成乱码。

解法简单粗暴——写文件时把encoding="utf-8"换成:

encoding="utf-8-sig"

utf-8-sig会悄悄在文件开头塞一个”我是UTF-8″的标记,Excel看到就乖乖显示中文了。要发给别人用Excel看的CSV,一律用utf-8-sig;只给程序自己读,用utf-8就行。

坑2:数据里本身有逗号

比如项目栏写着”午饭,和同事AA”,逗号会把一格劈成两格,整行错位。

好消息:csv模块写入时会自动给带逗号的内容加引号("午饭,和同事AA"),读的时候也能正确还原。只要读和写都用csv模块(而不是手动拼字符串,千万别f"{a},{b},{c}"自己拼),这个坑自动填平。

坑3:覆盖写,把原文件洗没了

open("账单.csv", "w")一执行,账单.csv原内容就没了。如果程序后面报错,数据就丢了。

安全习惯:写结果永远用新文件名(汇总.csv、结果.csv),永远别拿”w”模式对着原始数据文件写。

七、跟AI协作的正确姿势(阶段3特供)

阶段3开始接触”数据处理”,AI能帮你的地方更多了,但姿势要对:

  1. 描述数据,不只是描述功能。”帮我处理CSV”太模糊,”我的CSV表头是日期,项目,金额,有几百行,我想按项目汇总金额”才是好需求。AI知道你的数据长什么样,代码才写得准
  2. 拿到代码先读,再跑。数据处理的错误很隐蔽——比如坑1的字符串不转数字,程序跑得欢,结果全是错的。读懂每一块在干什么,比跑通更重要
  3. 报错+你的数据样本一起发给AI。比如”报错KeyError: ‘金额’,我的CSV前两行是这样的:……”,AI一看就知道是表头名字对不上
  4. 让AI帮你加”保险”。比如”帮我加上异常处理:金额那列如果不是数字,跳过这一行并告诉我”——好的数据处理程序,一半代码在处理”脏数据”

八、今日小练习

练习1:成绩排名表

做一个成绩.csv(自己造10行数据:姓名,语文,数学,英语),写程序算出每个人的总分和平均分,按总分从高到低排序,存成排名.csv。(提示:字典列表+sorted(key=...)——第十四篇生成器里用过的排序,换个key而已。)

练习2:通讯录查重

做一个通讯录.csv(姓名,电话),故意造几条重复的。写程序找出重复的电话号码,输出”电话xxx出现了n次”。(提示:又是单词统计器那招——字典累加器。你发现了吗,这招已经用三次了,它就是数据处理的”万能钥匙”。)

练习3:账单小工具加个功能

给第五节的账单整理小工具加两个功能:① 找出单笔金额最大的三笔支出;② 按月份(日期前缀”10-01″的”10″)汇总。(提示:sorted(key=lambda x: x["金额"])切片取前三;月份用字符串切片row["日期"][:2]。)

写在阶段3的开头

欢迎来到阶段3。前24篇你学会了”让程序干活”,从今天起学的是”让程序干活的对象从’几个数据’变成’一堆数据’“——CSV、JSON、数据清洗、批量处理、pandas。听着唬人,其实就是把字典列表那套基本功用在更大的数据上。

你已经在阶段2用12个项目把基本功打扎实了,接下来不过是把招式用在新场地上。

下篇预告

第二十六篇:CSV数据分析——一份几百行的真实数据,怎么快速看清它的全貌?平均值、最大值、分布规律,下一篇见。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注