Python 数据处理入门(一):环境准备与 5 分钟跑通第一个 Pandas 程序
这个系列面向完全没有数据处理经验的同学。你不用会算法、不用懂机器学习只要会一点点 Python 基础语法变量、函数、for 循环就能跟着把 12 篇走完。系列更新节奏是每天一篇顺序建议不要跳环境准备与第一个程序本篇Series 与 DataFrame把表格装进内存读文件CSV 与 Excel 的正确读法数据探查拿到一张表先看什么筛选与排序缺失值处理数据清洗类型、重复、异常值分组聚合Excel 透视表的代码版表的合并与拼接时间序列按周按月做统计数据分析常用可视化综合实战从脏数据到一份分析报告一、为什么是 Pandas先看一个很常见的场景一张 3000 行的订单表要按城市统计销售额还要筛出金额异常的单子。用 Excel 也能做但每次数据更新都要重新点一遍数据透视表而且容易漏步骤。用 Pandas 的做法是把这些操作写成代码import pandas as pd df pd.read_csv(data/sales.csv) print(df.groupby(城市)[金额].sum())跑一次是它跑一百次还是它。数据换了脚本不用改。Pandas 是 Python 生态里最主流的数据处理库优点很实在能装得下几十万行的表格在内存里随便操作不受 Excel 104 万行和手动操作的掣肘API 统一读取、筛选、分组、合并、导出都是同一套写法生态好和 NumPy、Matplotlib、scikit-learn 无缝衔接后面想画图、做分析、跑模型都不用换工具。一句话Pandas 是「用代码操作表格」的标准答案。二、装 Python 和 Pandas1. 选哪个 Python 发行版两个选择任选其一Anaconda适合学生和新手装完自带 Pandas、NumPy、Jupyter省心缺点是体积大几个 GB官方 Python pip 装包体积小、干净适合已经写过 Python 的同学。本文按第二种来写Anaconda 用户跳过安装步骤即可。2. 装 Pandas打开终端Windows 是 CMD 或 PowerShellmacOS 是终端执行pip install pandas openpyxlpandas数据处理主角openpyxl读写.xlsx文件要用它很多人读 Excel 报错就是漏了这个包。国内下载慢的话加个镜像pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple3. 验证环境python -c import pandas as pd; print(pd.__version__)3.0.1能打印出版本号本文示例环境是3.0.1就说明装好了。本系列代码在pandas 2.x / 3.x上都可以跑。小提示本系列的代码在 PyCharm、VS Code、Jupyter Notebook 里都能跑。新手建议先用 VS Code 或 PyCharm 建一个.py文件比 Notebook 更容易养成完整的脚本思维。三、第一个程序不读文件也能玩不急着找数据Pandas 可以直接用 Python 的字典造一张小表import pandas as pd df pd.DataFrame( { 城市: [杭州, 上海, 北京, 杭州], 销量: [120, 95, 60, 88], } ) print(df) print(总销量, df[销量].sum())运行结果城市 销量 0 杭州 120 1 上海 95 2 北京 60 3 杭州 88 总销量 363四行代码就跑完了「造表 → 打印 → 求和」。df就是一张内存里的表格df[销量]取出其中一列。四、Pandas 处理数据的固定套路后面所有文章其实都在重复这五步步骤做什么常用方法1. 读取把文件读成 DataFrameread_csv/read_excel2. 查看先看清数据长什么样head/info/describe3. 清洗处理空值、重复、类型、异常dropna/fillna/astype4. 分析筛选、排序、分组、合并布尔索引 /groupby/merge5. 输出导出结果或画图to_excel/plot记住这张表你就有了一张「遇到问题该用哪个方法」的地图。五、准备示例数据一次生成玩 11 篇为了后面每篇都有真实数据可练我们先写一个造数据的脚本mkdata.py。它会在当前目录生成data/文件夹里面有销售、学生成绩、员工、订单、股票等几份 CSV其中故意混入了空值、重复行和异常值第 6、7 篇清洗时会用到。新建mkdata.py把下面代码完整粘进去# -*- coding: utf-8 -*- 生成系列文章里用的示例数据练习数据 有瑕疵的脏数据。 import os import numpy as np import pandas as pd OUT data def _ensure_out(): 确保输出目录存在避免 to_csv 报“目录不存在”。 os.makedirs(OUT, exist_okTrue) def make_sales(): 销售明细表故意留了空值、重复行、异常值。 _ensure_out() df pd.DataFrame( { 订单日期: [ 2024-01-05, 2024-01-06, 2024-01-06, 2024-01-09, 2024-02-03, 2024-02-11, 2024-02-11, 2024-03-02, 2024-03-15, 2024-03-15, 2024-04-01, 2024-04-18, 2024-04-18, 2024-05-06, 2024-05-20, 2024-05-20, ], 城市: [ 杭州, 上海, 上海, 北京, 杭州, 广州, 广州, 北京, 上海, 上海, 杭州, None, 北京, 广州, 杭州, 杭州, ], 产品: [ A-笔记本, B-鼠标, B-鼠标, C-键盘, A-笔记本, B-鼠标, B-鼠标, A-笔记本, C-键盘, C-键盘, B-鼠标, A-笔记本, D-显示器, C-键盘, D-显示器, D-显示器, ], 数量: [3, 5, 5, 2, 4, 6, 6, 1, 7, 7, 2, 3, 2, 4, 5, 5], 单价: [ 49.9, 29.9, 29.9, 89.0, 49.9, 29.9, 29.9, 49.9, 89.0, 89.0, 29.9, 49.9, 599.0, 89.0, 599.0, 599.0, ], 销售员: [ 小张, 小李, 小李, 小王, 小张, 小赵, 小赵, 小王, 小李, 小李, 小张, 小赵, 小王, 小李, 小张, None, ], } ) df[金额] (df[数量] * df[单价]).round(2) df.loc[[5, 12], 金额] np.nan # 模拟系统没算出金额 df.loc[14, 金额] -599.0 # 模拟录入错误 df.to_csv(f{OUT}/sales.csv, indexFalse, encodingutf-8-sig) return df def make_students(): 学生成绩表有缺失成绩、重复学号、文本型数字。 _ensure_out() df pd.DataFrame( { 学号: [ 2024001, 2024002, 2024003, 2024004, 2024005, 2024005, 2024006, 2024007, 2024008, 2024009, 2024010, 2024011, ], 姓名: [ 张小明, 李小红, 王大力, 赵小美, 陈小强, 陈小强, 刘小燕, 杨小帆, 周小雨, 吴小磊, 郑小云, 孙小虎, ], 班级: [ 一班, 一班, 二班, 二班, 一班, 一班, 三班, 三班, 二班, 三班, 一班, 三班, ], 性别: [ 男, 女, 男, 女, 男, 男, 女, 男, 女, 男, 女, 男, ], 语文: [88, 92, None, 79, 95, 95, 68, 73, 84, 90, 76, 61], 数学: [92, 85, 78, 88, None, None, 71, 65, 90, 94, 69, 58], 英语: [85, 90, 82, None, 88, 88, 74, 80, 86, 91, 72, 66], } ) df.to_csv(f{OUT}/students.csv, indexFalse, encodingutf-8-sig) return df def make_employees(): 员工表数字列里混进了文本和空值。 _ensure_out() df pd.DataFrame( { 工号: [E01, E02, E03, E04, E05, E06, E07, E08], 姓名: [张伟, 王芳, 李娜, 刘洋, 陈静, 杨波, 赵敏, 周涛], 部门: [技术部, 市场部, 技术部, 人事部, 市场部, 技术部, 人事部, 市场部], 入职日期: [ 2021-03-01, 2020-07-15, 2022-09-01, 2019-05-20, 2023-01-09, 2021-11-03, 2022-04-18, 2023-06-26, ], 月薪: [12000, 9500, 15000, 8000, None, 18000, 8500, 10500], 绩效分: [4.5, 3.8, 4.8, 3.5, 4.0, 4.9, 3.9, 4.2], } ) df.to_csv(f{OUT}/employees.csv, indexFalse, encodingutf-8-sig) return df def make_orders_messy(): 订单表 客户表用来练 merge 和 concat。 _ensure_out() orders pd.DataFrame( { 订单号: [A001, A002, A003, A004, A005, A006], 客户ID: [C01, C02, C03, C02, C05, C01], 下单日期: [ 2024-01-08, 2024-01-19, 2024-02-02, 2024-02-23, 2024-03-05, 2024-03-21, ], 订单金额: [320.0, 158.5, 990.0, 420.0, 88.0, 265.5], } ) customers pd.DataFrame( { 客户ID: [C01, C02, C03, C04], 客户名称: [恒信科技, 云图文化, 海通物流, 光年传媒], 所在城市: [杭州, 上海, 北京, 广州], 客户等级: [A, B, A, C], } ) orders.to_csv(f{OUT}/orders.csv, indexFalse, encodingutf-8-sig) customers.to_csv(f{OUT}/customers.csv, indexFalse, encodingutf-8-sig) return orders, customers def make_orders_xlsx(): Excel 双 sheet明细 按城市汇总。 _ensure_out() df make_sales() with pd.ExcelWriter(f{OUT}/sales.xlsx, engineopenpyxl) as writer: df.to_excel(writer, sheet_name明细, indexFalse) ( df.groupby(城市, dropnaFalse) .agg(订单数(数量, size), 销量(数量, sum), 销售额(金额, sum)) .reset_index() .to_excel(writer, sheet_name按城市汇总, indexFalse) ) def make_stock(): 时间序列某只股票 30 个交易日的收盘价。 _ensure_out() rng np.random.default_rng(7) days pd.bdate_range(2024-01-02, periods30) close 100 np.cumsum(rng.normal(0, 1.6, len(days))).round(2) df pd.DataFrame( {日期: days, 收盘价: close, 成交量: rng.integers(8000, 26000, len(days))} ) df.to_csv(f{OUT}/stock.csv, indexFalse, encodingutf-8-sig) return df def main(): _ensure_out() make_sales() make_students() make_employees() make_orders_messy() make_orders_xlsx() make_stock() print(示例数据已生成到 ./data 目录) for name in sorted(os.listdir(OUT)): print( -, name) if __name__ __main__: main()然后运行它import runpy # 以 __main__ 身份执行脚本等价于在命令行敲 python mkdata.py runpy.run_path(mkdata.py, run_name__main__)看到下面这样的输出就成功了示例数据已生成到 ./data 目录 - customers.csv - employees.csv - orders.csv - sales.csv - sales.xlsx - stock.csv - students.csv顺手验证一下数据能读进来import pandas as pd df pd.read_csv(data/sales.csv, encodingutf-8-sig) print(df.shape) print(df.head(3))(16, 7) 订单日期 城市 产品 数量 单价 销售员 金额 0 2024-01-05 杭州 A-笔记本 3 49.9 小张 149.7 1 2024-01-06 上海 B-鼠标 5 29.9 小李 149.5 2 2024-01-06 上海 B-鼠标 5 29.9 小李 149.5(16, 7)表示 16 行 7 列说明数据已经躺在 Python 里了。六、新手最容易踩的三个坑1. 报错ModuleNotFoundError: No module named pandas库没装上或者装到了另一个 Python 环境里。先执行python -m pip install pandas确认python -c import pandas能过。2. 读取 Excel 报错Missing optional dependency openpyxl按提示补装即可pip install openpyxl。3. 打印中文乱码 / 读 CSV 报 UnicodeDecodeErrorWindows 终端默认是 GBK 编码而数据文件通常是 UTF-8。两个处理办法读取时显式指定编码pd.read_csv(data/sales.csv, encodingutf-8-sig)本系列统一这么写或者在脚本开头加import sys; sys.stdout.reconfigure(encodingutf-8)。小结这一篇做了三件事装好 Pandas、跑通第一个程序、生成一份贯穿全系列的示例数据。下一篇开始正式进入正题Series 和 DataFrame 到底是什么怎么取一列、取一行、按条件取一片。把这两个对象的脾气摸清了后面所有操作都会顺很多。