ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Python实战第四周:从文件读写到数据可视化完整流程

Python实战第四周:从文件读写到数据可视化完整流程 Python学到第四周上我终于从“抄教程”切换到“自己动手写个小工具”的状态。这个过程最大的感触不是语法变难了而是问题突然变得具体文件编码不对、日期格式不认识、画出来的图横坐标挤成一团……每个问题都能让你在搜索引擎里泡半天。如果你也处于“基础语法都会但一看项目就懵”的阶段这周的学习记录应该能给你一点参考。我会把本周前半程踩过的坑、封装代码的思路、以及几个能直接抄作业的解决办法都写出来。1. 学习路线与准备阶段1.1 为什么第四周才开始转实战很多入门教程会把语法、流程控制、函数、面向对象一路讲下去结果学到后面才发现自己只会做课后题。我给自己定的节奏是前三周老老实实过完基础语法和常用数据结构第四周开始必须用真实场景把知识串起来。真实的场景不一定要多复杂哪怕只是把自己电脑里的某个CSV文件读出来、做点简单统计也比单纯刷题能暴露更多问题。第四周上我给自己定的任务很具体输入一个本地气温记录文件输出一周的最高温、最低温和平均温并且画一张折线图。这个任务会自然牵扯出三块内容文件读写、数据清洗类型转换、数据可视化。它既不要求你懂复杂的面向对象也不会因为太简单而让人失去兴趣正好卡在“跳一跳够得着”的位置上。1.2 环境和工具再检查开始写代码前我重新整理了一遍环境。我用的是VS CodePython是3.10版本。这里有个容易被新手忽略的点VS Code里装好Python插件后右下角会显示当前解释器路径。如果你在终端里敲python能运行但VS Code里却报错八成是解释器没选对。设置方法很简单按CtrlShiftP输入Python: Select Interpreter选你安装的那个版本就行。另外我强烈建议从第四周开始使用虚拟环境。别觉得它麻烦实际上一行命令就能创建python -m venv .venvWindows下激活方式是.venv\Scripts\activatemacOS或者Linux下是source .venv/bin/activate。激活后终端前面会出现(.venv)之后就只在当前项目里装包不会把系统环境搅乱。装包时我直接用了国内镜像源不然某些依赖包下载速度会让人怀疑人生。以清华源为例pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple实测下来速度快很多而且不太会遇到超时中断。如果你只想临时换源用上面这种方式就够了想一劳永逸可以用pip config set global.index-url设置全局索引地址。提示第四周开始尽量不要再把所有代码塞在一个脚本里。哪怕只是拆成“数据处理”和“画图”两个函数后面改起来都会舒服很多。2. 核心知识点文件处理与类型转换2.1 文件读写的基础姿势我准备的气温数据文件是weather.csv格式是date,temp 2025-01-01,3.5 2025-01-02,4.1 2025-01-03,-1.2 ...第一版代码我直接用了open加readlines结果读出来全是字符串还要自己处理结尾换行。后来发现Python标准库里的csv模块更省心import csv with open(weather.csv, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: print(row)这里必须要提一下with的作用。with open(...) as f会自动管理文件的关闭。如果不用with你得记得写f.close()万一中间抛异常文件句柄就可能一直占着。在这个小例子里可能看不出差别但程序一旦跑起来文件打开多了会出各种奇怪问题。encodingutf-8也很关键。Windows上很多编辑器默认存成gbk如果你直接读会看到UnicodeDecodeError或者满屏乱码。我建议所有读写文本文件的代码都显式写上编码别偷懒。2.2 字符串转数字和日期解析的细节CSV读进来的数据全是字符串这就到了热词里常说的“类型转换”环节。temp列要变成浮点数才能计算date列要变成日期对象才能排序或者按星期分组。直接float(3.5)没有问题但如果你文件里有空行或者表头带空格就会抛ValueError。我在真实数据里遇到过一行数据是2025-01-04,逗号后面什么都没有float()直接报错。解决办法是加一个判断def safe_float(value): try: return float(value) except ValueError: return None日期解析用datetime.strptime它需要你告诉Python日期的格式。比如from datetime import datetime date_str 2025-01-01 date_obj datetime.strptime(date_str, %Y-%m-%d)这里%Y是四位的年份%m是两位的月份%d是两位的日期顺序要和字符串里的顺序完全一致。如果你数据里写的是2025/01/01那格式就得是%Y/%m/%d。这类细节特别容易让人血压升高但踩过一次之后你遇到任何格式的日期都会有感觉。2.3 写一个小工具把乱数据变成干净表格既然要处理真实数据我顺手写了一个清洗逻辑读取每一行过滤掉坏数据把日期和温度都转成正确的类型最后存入一个新的列表。这有点像把一堆散乱的积木先分好类后面统计和画图才只用关心有用的部分。import csv from datetime import datetime def load_data(filename): records [] with open(filename, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: temp safe_float(row[temp]) if temp is None: continue try: date_obj datetime.strptime(row[date], %Y-%m-%d) except ValueError: continue records.append({date: date_obj, temp: temp}) return records这里把“脏数据”和“好数据”分开的思路很关键会让你之后的统计代码不被异常打断。很多刚接触Python的朋友一看到try...except就觉得是高级用法其实它就是用一种更优雅的方式处理“可能会出错”的情况。你完全可以先跑一遍代码等真的抛异常了再去补对应的except慢慢就会形成条件反射。3. 实战小项目用Python统计并可视化一周气温3.1 项目需求拆解数据加载好了下一步就是统计。我给自己的要求是输出这一周的最高温度、最低温度、平均温度并画一张折线图展示每天的温度变化。这个需求拆开来看就三件事一轮循环找最大值和最小值一个累加算平均值最后调用matplotlib画图。表面看很简单但真正写起来会发现“最大值对应哪一天”才是真正的需求。如果只输出一个数字图里没法对应那就没意义。所以我最后决定统计结果做成一个列表每个元素包含日期、温度、是否最高、是否最低。这样既能画图也能在图上把最高点和最低点标出来。max_temp max(records, keylambda x: x[temp]) min_temp min(records, keylambda x: x[temp]) avg_temp sum(x[temp] for x in records) / len(records)这里key参数用来指定比较的字段lambda表达式返回每个记录的温度max和min就会按温度求值。如果你直接max(records)它比较的是日期对象还是温度大概率会报错因为Python不知道该怎么比较两个字典。这个坑在初学者里非常普遍。3.2 数据清洗与统计逻辑统计单独写成一个函数把“从数据到结果”的逻辑和“读取文件”的逻辑分开。这样做的好处是之后你不想读CSV改成从接口拿数据统计函数一个字都不用改。def analyze(records): if not records: return None max_record max(records, keylambda x: x[temp]) min_record min(records, keylambda x: x[temp]) avg_temp sum(x[temp] for x in records) / len(records) return { max: max_record, min: min_record, avg: avg_temp, days: len(records), }我自己一开始把统计逻辑全写在主流程里结果画图时又要重新取温度列表代码越写越长。后来拆成几个小函数主流程变成三行records load_data(weather.csv) stats analyze(records) plot_temperature(records, stats)这就是典型的“函数封装”思维。第四周上不需要学得多高深先把“一个函数只做一件事”形成习惯后面接触面向对象会轻松很多。3.3 matplotlib画图时横坐标太密集的三种解法画图这块我严重怀疑每个初学者都会遇到“横坐标太密集”这个问题。数据量一旦超过10个点matplotlib默认会把每个日期都显示出来文字叠在一起根本看不清。我的第一版代码长这样import matplotlib.pyplot as plt dates [x[date] for x in records] temps [x[temp] for x in records] plt.plot(dates, temps) plt.show()出来的图坐标轴上一堆年月日像一条毛毛虫。后来我查资料才知道matplotlib不会自动帮你减少刻度它只会傻乎乎地把所有刻度标签都画出来。于是我开始尝试三种办法效果都很直接。第一种是旋转刻度文字。把日期标签旋转45度错位之后至少能看清大部分plt.xticks(rotation45)第二种是“隔几个显示一个”。如果你有30天数据每5天显示一个标签就够了。用plt.xticks配合切片ticks dates[::5] plt.xticks(ticks, [d.strftime(%m-%d) for d in ticks], rotation45)第三种是直接让画布变得更宽用plt.figure(figsize(12, 5))。把图片横向拉长标签之间自然就有空间了。实际项目中我一般组合使用画布调宽、标签切片、旋转45度三者一起上。方法适用场景代码要点旋转标签数据量小于15个时plt.xticks(rotation45)间隔显示刻度数据量较大或不想显示所有日期ticks dates[::5]加宽画布希望保留更多刻度细节plt.figure(figsize(12, 5))3.4 用函数封装代码结构画图函数我保留了两个参数一个数据、一个统计结果这样以后换数据文件还能复用。def plot_temperature(records, stats): dates [x[date] for x in records] temps [x[temp] for x in records] plt.figure(figsize(10, 5)) plt.plot(dates, temps, markero, labeltemperature) plt.scatter(stats[max][date], stats[max][temp], colorred, labelmax) plt.scatter(stats[min][date], stats[min][temp], colorblue, labelmin) plt.axhline(stats[avg], colorgray, linestyle--, labelavg) plt.legend() plt.xticks(rotation45) plt.tight_layout() plt.show()这里的axhline用来画一条水平参考线我用来标记平均温度非常直观。tight_layout()会自动调整子图参数让标签不超出画布边界。每次画完图我都习惯加这一句能省去很多手动调布局的时间。这样一个完整的小项目就算落地了。我运行完程序后终端里能看到最高温、最低温和平均值弹窗里能看到带最高点、最低点和平均参考线的折线图。虽然代码总共可能不到一百行但它完整覆盖了“读取—清洗—统计—展示”这个数据处理的闭环。4. 常见问题与排查技巧实录4.1 中文乱码不是玄学我最早打开CSV文件时终端里直接冒出各种乱码。排查下来发现文件本身是UTF-8编码但我的Windows终端默认用GBK解码。解决方式要看“谁在乱码”如果是print输出到终端乱码先试chcp 65001切换代码页如果是读取文件乱码就把open里的encoding参数改成utf-8或gbk以实际文件编码为准。还有一个很容易忽略的是Python脚本文件本身的编码。如果你的脚本里写了中文注释而文件保存成了GBKPython 3运行时会默认按UTF-8读取也可能报语法错误。解决办法是在VS Code右下角把文件编码改成UTF-8再重新保存。4.2 找不到python命令怎么办很多Windows用户装完Python之后在终端输python弹出来的却是微软商店的页面或者提示python was not found。这个问题十有八九是安装时没有勾选Add Python to PATH。不用急着重装最简单的办法是用py命令启动Pythonpy --versionpy是Windows自带的Python启动器如果你电脑里装了多个Python版本它还能帮你选择版本。如果你还是希望python命令能用那就去“设置”里搜索“环境变量”把Python的安装目录和Scripts目录加进Path。这一步做完之后新开的终端窗口才会生效。4.3 安装matplotlib失败或特别慢刚开始装matplotlib时我遇到的是“超时”和“找不到匹配版本”的报错。后来发现主要原因是网络源的问题。换成国内镜像之后问题基本消失。这里要注意不同的包可能依赖底层库比如matplotlib在Windows上需要numpy等一堆依赖如果你只用默认源下载这些依赖会非常痛苦。用-i参数加上合适的镜像地址一条命令全部搞定。如果你在某个项目里需要反复装依赖也可以把镜像地址写进requirements.txt旁边的一个配置文件里但这些都是后话。入门阶段记住“装包慢就换源”这一个技巧就够了。4.4 协程和多进程是怎么回事第四周上我还没有正式进入协程和多进程的学习但写循环处理数据时隐约感觉到如果数据量再大一点单线程跑起来会很慢。于是提前了解了一下概念协程适合处理“等待型”任务比如网络请求多进程适合处理CPU密集型的计算任务。它们并不是用来解决“我这段代码会不会更快”的万能工具更多时候正确的数据结构、合理算法反而更关键。我目前的态度是先把常规代码写对等真正遇到性能瓶颈再回头针对性地引入这些并发工具。很多初学者一上来就想用协程炫技结果连标准库的回调机制都没搞明白最后Debug到怀疑人生。四周的学习进度里先把基础打牢永远是第一优先级。注意如果某个任务用单线程明明几秒钟就能跑完就别急着上多进程。进程之间通信带来的麻烦可能比节省的那点时间贵得多。5. 学习节奏与心态调整第四周上最大的收获不是学会了几个函数而是终于明白“照着教程能跑通”和“自己写出来”是两码事。每次遇到报错别急着去复制答案先自己读一遍报错信息猜一猜它在说什么。Python的报错已经非常友好了大部分时候它会告诉你发生在哪一行甚至给出对应建议。我现在的习惯是哪怕代码写错了也先自己写一个“错误版本”再根据报错慢慢改成正确版本。这个过程比直接看十篇教程都管用。第四周上的时间其实很紧能完成一个从读到画的小闭环已经很不错了。后半周我打算在这个项目上继续扩展比如把统计结果输出成一份文本报告或者增加“按周筛选”的功能让这个小小工具的实用性再上一个台阶。
返回列表