
零基础学习 Python 数据分析绕不开 NumPy、Pandas、Matplotlib 三件套。很多人收藏了大量教程却卡在同一个位置不知道先装什么、装完后不知道从哪个例子开始、运行报错也不知道该看哪一行。这篇文章会从安装环境开始用一份订单数据贯穿完整的分析流程依次讲清 NumPy 的数值计算、Pandas 的表格处理和 Matplotlib 的绘图最后给出常见报错的排查路径。读者不需要有数据结构和算法基础只要能在电脑上运行命令行就可以按顺序完成一个最小的数据分析闭环准备数据、读取数据、清洗数据、分组统计、画图、验证结论。1. 先理解三件套的分工再动手写代码数据分析不是某一个库的功劳而是几个库接力完成的结果。很多初学者把三个库混在一起学看到哪个函数就记哪个最后写出的代码逻辑混乱。先理清分工后面每一步才有明确目的。1.1 三件套各管什么NumPy 提供的是多维数组对象ndarray负责数值计算。它可以理解为一个高效的数字容器支持向量化运算也就是说对数组里的所有元素执行同一个操作时不需要写 for 循环。Pandas 构建在 NumPy 之上提供Series和DataFrame两种数据结构负责表格数据的读取、清洗、筛选、分组、合并和聚合。Matplotlib 负责把分析结果画成图它既能画简单折线也能组合多子图是所有 Python 可视化方案的底层基础。一句话概括它们的关系NumPy 是计算引擎Pandas 是表格工作台Matplotlib 是报告输出端口。实际项目里Pandas 内部大量使用 NumPy 的数组和函数Matplotlib 又经常接收 NumPy 数组或 Pandas 列作为绘图数据。1.2 一条典型的数据分析链路一个完整的数据分析任务通常按下面这个顺序推进明确要回答什么问题。例如哪类商品销售额最高哪个区域订单量增长最快准备原始数据。常见来源是 CSV、Excel、数据库导出文件或接口返回的 JSON。读取数据并检查质量。看字段类型、缺失值、重复值、异常值。清洗数据。补缺失值、去重、转换日期格式、修正类型。计算指标。用 groupby、sum、mean 等完成分组聚合。可视化。用折线、柱状、饼图、散点图表达结论。验证结果。用小样本手工计算或交叉核对 SQL 查询结果。下面会严格按照这条链路展开。先把环境安装完成因为后面所有代码都依赖环境一致性。2. 环境准备先解决 Python 和依赖版本问题零基础阶段最容易踩的坑不是代码写错而是环境配置不一致。同一段代码在 A 机器能跑在 B 机器报错大部分原因是 Python 版本或库版本不一致。所以第一步不是急着写 NumPy 代码而是统一安装方式。2.1 选择安装方式Miniconda、Anaconda 或 Python 加 pip常见的安装方案有三种方案适合人群优点缺点Anaconda完全零基础希望开箱即用自带 Python、NumPy、Pandas、Matplotlib、Jupyter 等大量工具安装包较大占用空间多Miniconda想控制体积又希望用 conda 管理环境安装包小按需安装数据科学库需要手动安装常用库官方 Python 加 pip已有 Python 基础偏开发环境环境干净贴合普通 Python 工程需要手动管理和兼容版本推荐零基础用户优先考虑 Miniconda 或官方 Python 加虚拟环境。原因有三点环境隔离更清晰卸载不残留换新电脑时好复现。标题里提到的配套安装包实际是服务于安装不便或离线安装的场景但无论用哪种方式都建议在官网下载当前维护的稳定版本不要使用来历不明的第三方包。2.2 用 pip 最小安装三件套如果已经安装了 Python 3.9 或更高版本可以直接在终端执行python -m pip install --upgrade pip pip install numpy pandas matplotlib这会把三个库一起安装pip 会自动拉取当前 Python 版本兼容的依赖。安装完成后需要确认安装位置和版本避免后面 import 时找到另一个 Python 环境。如果使用 conda可以执行conda create -n>python -c import numpy, pandas, matplotlib; print(numpy.__version__); print(pandas.__version__); print(matplotlib.__version__)如果输出三个版本号说明环境正常。如果报ModuleNotFoundError先检查当前激活的 Python 环境which python python -m pip listwhich python能看清解释器路径。很多时候不是库没装而是终端里的 Python 和 pip 指向的不是同一个环境。2.4 关于“配套安装包”和版本选择的落地建议教程标题里的“2026 最新版本”指的是当前官方持续更新的版本具体版本号要以安装时官网展示和 pip 输出为准不要根据教程发布日期强行固定到某个版本。配套安装包只适合离线环境正常开发建议使用在线安装好处是能同时解决依赖关系。安装完成后把下面这份环境信息保存下来后面排错会用到python --version pip list如果项目中已有requirements.txt可以一键恢复环境pip install -r requirements.txt常见坑是直接把pip install numpy和conda install numpy混着用。混用容易导致同一个环境出现两套依赖树轻则库版本异常重则 Python 崩溃。建议选择一个包管理工具主用。3. 从零创建一个最小数据分析项目销售订单统计环境准备好后不要直接学语法而是先跑通一个小项目。这里以销售订单为背景一份 CSV 文件里包含订单编号、日期、商品、分类、数量、单价、成本和区域需要计算不同商品的销售额和利润并按区域画柱状图。3.1 项目目标与目录结构项目要回答三个问题总销售额是多少哪个商品分类销售额最高哪个区域销售额最高目录结构如下data-analysis/ ├── data/ │ └── orders.csv ├── analysis.py └── output/ └── sales_by_region.pngdata放原始数据analysis.py放分析脚本output放图表结果。如果只跑一次目录可以简化但养成“数据、代码、输出分离”的习惯后项目才有复现价值。3.2 用 CSV 准备测试数据如果没有真实数据可以用一个简单的 CSV 文件模拟。新建data/orders.csv内容如下order_id,date,product,category,quantity,unit_price,cost,region A001,2025-01-03,无线鼠标,外设,3,89,45,华东 A002,2025-01-05,机械键盘,外设,2,299,180,华南 A003,2025-01-08,27寸显示器,显示器,1,999,650,华东 A004,2025-01-12,无线鼠标,外设,5,89,45,华北 A005,2025-01-15,机械键盘,外设,1,299,180,华南 A006,2025-01-19,USB扩展坞,外设,4,129,70,华北 A007,2025-01-22,27寸显示器,显示器,2,999,650,华东 A008,2025-02-01,无线鼠标,外设,2,89,45,华南 A009,2025-02-06,27寸显示器,显示器,1,999,650,华北 A010,2025-02-10,USB扩展坞,外设,3,129,70,华东这份数据足够小而全包含日期、分类、数量、金额和区域字段可以直观看到分组统计的结果。3.3 读取数据并查看基本情况在analysis.py中先写读取部分import pandas as pd df pd.read_csv(data/orders.csv) print(df.head()) print(df.info())运行python analysis.pyhead()能查看前几行info()能查看每列的非空数量和数据类型。这一步不是形式而是在确认日期列是否被识别为文本数量列是否读成了数字有没有列出现缺失值。这里有一个零基础频繁踩的坑CSV 文件路径。脚本从哪个目录启动相对路径就相对于哪个目录。如果从项目根目录运行data/orders.csv能正确找到如果从其他目录运行就会报FileNotFoundError。推荐脚本开头加一段路径保护from pathlib import Path BASE_DIR Path(__file__).resolve().parent df pd.read_csv(BASE_DIR / data / orders.csv)这样无论从哪个目录执行都能按脚本所在位置定位文件。4. NumPy 数值运算先理解数组和广播在进入 Pandas 分组统计之前先花一点时间看 NumPy因为 Pandas 的列本质上是带索引的 NumPy 数组理解数组后才能理解为什么很多运算不需要循环。4.1 创建 ndarray 与基本切片创建一个二维数组import numpy as np arr np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) print(arr.shape) print(arr[:, 1])运行结果(3, 3) [20 50 80]arr.shape返回(3, 3)表示三行三列。arr[:, 1]表示取所有行、第 1 列结果是一个一维数组。这个切片写法在 Pandas 里被扩展成了更丰富的.loc和.iloc但思想是一样的先确定行范围再确定列范围。4.2 广播机制与向量化计算NumPy 的核心优势不是少写几行代码而是底层使用连续内存和 C 语言实现的高速计算。看下面这段prices np.array([89, 299, 999, 129]) new_prices prices * 1.2 print(new_prices)这里prices * 1.2会把所有元素同时乘以 1.2不需要写循环。NumPy 会自动把标量1.2扩展成与数组形状相同的结构再逐一计算这个机制叫广播。广播也适用于不同形状的数组例如a np.array([[1], [2], [3]]) b np.array([10, 20, 30]) print(a b)输出[[11 21 31] [12 22 32] [13 23 33]]理解广播的意义在于数据分析中的“对整列做运算”在底层大部分就是这样实现的。遇到维度不匹配时NumPy 不是报错就是产生不符合预期的结果这也是新手常遇到的could not broadcast input array from shape错误来源。4.3 常用统计函数NumPy 提供了很多直接可用的统计函数arr np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) print(arr.sum()) print(arr.mean(axis0)) print(arr.var()) print(arr.std())axis0按列方向计算axis1按行方向计算。实际数据处理中最常见的需求是求总销售额、平均值、标准差。Pandas 的df[单价].mean()底层就调用这类函数。注意一个坑不要用 Python 内置list去套用 NumPy 函数。np.mean([1, 2, 3])虽然能用但大列表性能明显下降。正规做法是把数据先转成np.array。5. Pandas 表格处理从清洗到分组聚合Pandas 是数据分析的核心工作台。接下来把orders.csv完整处理一遍包括计算销售额、清洗缺失值、转换日期、分组汇总和多表合并。5.1 认识 Series 和 DataFramePandas 的DataFrame可以理解为带行索引和列名的表格Series是它的单列。把 CSV 读进来后df[quantity]返回的就是一个 Series可以对这个列做加减乘除和统计。df[销售额] df[quantity] * df[unit_price] df[利润] df[销售额] - df[quantity] * df[cost] print(df[[product, quantity, 销售额, 利润]].head())这里新增了两列。不要直接修改原始 CSV应该通过变量df保存结果。后面如果需要导出再调用to_csv。推荐做法是在脚本开头完成加载后复制一份原始数据raw_df df.copy()这样清洗过程如果出错可以直接回到raw_df重新开始不需要重新读文件。5.2 缺失值处理和数据类型转换真实数据很少像模拟数据这样干净。常见情况是某几行unit_price为空某几行日期格式混乱。Pandas 会把这些缺失值表示为NaN。判断缺失值可以这样print(df.isna().sum())处理缺失值有两种思路删除或填充。删除适合缺失比例很低的情况填充适合需要保留行的情况。df df.dropna(subset[unit_price]) df[unit_price] df[unit_price].fillna(df[unit_price].median())dropna删除指定列有缺失的行fillna用中位数填充。中位数比平均值更抗异常值价格列出现极端大单时平均价会被拉高。数据类型转换也容易出错。比如订单日期有时会被读成字符串直接用 Pandas 的日期操作会失败。正确做法是显式转换df[date] pd.to_datetime(df[date]) df[month] df[date].dt.to_period(M)to_datetime能把字符串转成时间类型dt.to_period(M)能把日期聚合到月份。如果原始日期格式不是YYYY-MM-DD需要传入format参数例如pd.to_datetime(df[date], format%Y/%m/%d)常见坑是忽略format导致 Pandas 按默认格式解析遇到2025/01/03或03/01/2025时产生误判。日期字段建议在加载后立即用print(df[date].dtype)确认类型。5.3 分组聚合和排序分组聚合是数据分析里最常用的操作。比如计算每个商品的销售额sales_by_product ( df.groupby(product, as_indexFalse)[销售额] .sum() .sort_values(销售额, ascendingFalse) ) print(sales_by_product)groupby(product)把相同商品的订单放在一组[销售额].sum()对每组求和sort_values按销售额排序。输出大致为product 销售额 0 27寸显示器 3996 1 无线鼠标 890 2 机械键盘 897 3 USB扩展坞 903如果想同时看多个指标可以用aggstats df.groupby(category).agg( 订单数(order_id, count), 总销售额(销售额, sum), 平均销售额(销售额, mean), 平均利润(利润, mean), ) print(stats)agg内用元组指定“列名聚合函数”比逐个写groupby(...).sum()更清晰也能避免链式调用过长。5.4 多表合并实际数据很少只有一个表。客户信息、商品信息、区域信息可能分散在不同文件。假设有一个products.csv保存商品分类的详细信息product,category,stock 无线鼠标,外设,500 机械键盘,外设,120 27寸显示器,显示器,45 USB扩展坞,外设,300用 Pandas 合并两个表products pd.read_csv(data/products.csv) merged pd.merge(df, products, onproduct, howleft) print(merged.head())on指定关联字段howleft表示保留左侧表所有订单记录右侧没有匹配时显示NaN。实际项目中how的选择决定了保留范围初学者最常犯的错误是默认使用内连接丢失了没有匹配上的订单。常见坑是关联字段名称不一致比如一个叫product另一个叫product_name。可以先统一products products.rename(columns{product_name: product})5.5 链式调用的可读性问题Pandas 代码很容易写成一长串。零基础阶段建议每步赋给一个变量并用注释说明目的不要追求“一行代码完成所有操作”。下面两种写法结果一样但第二种更适合学习# 不推荐 result df[df[region] 华东].groupby(product)[销售额].sum().sort_values(ascendingFalse) # 推荐 region_df df[df[region] 华东] by_product region_df.groupby(product)[销售额].sum() result by_product.sort_values(ascendingFalse)代码长了以后先保留中间变量能明显减少排错时间。6. Matplotlib 数据绘图把结果变成图计算出的表格虽然能说明问题但很难直接放进汇报文档。Matplotlib 负责把结果可视化。绘图前要先分清几个概念画布、坐标轴和图形对象。6.1 画布、坐标系与坐标轴比例plt.figure(figsize(8, 5))创建一张宽 8 英寸、高 5 英寸的画布。figsize决定图片尺寸不是像素大小导出图片时才由dpi决定清晰度。画布上可以有多个坐标系axes每个坐标系是一张子图。一个常见需求是让 X 轴和 Y 轴单位长度一致。比如画正方形、圆形或真实地理坐标时如果不等比例圆形会被压成椭圆。可以这样控制import matplotlib.pyplot as plt fig, ax plt.subplots() ax.plot([0, 1, 2], [0, 1, 0]) ax.set_aspect(equal) plt.show()set_aspect(equal)使坐标轴比例一致。如果比例不一致加上圆形数据会看起来变形。这在热词里也频繁出现说明不少人被“图变形”困扰。6.2 常用图形柱状图、折线图、饼图、散点图柱状图适合对比分类数据。以区域销售额为例sales_by_region df.groupby(region)[销售额].sum().sort_values() plt.figure(figsize(8, 5)) plt.bar(sales_by_region.index, sales_by_region.values, color[#4C72B0, #DD8452, #55A868]) plt.title(各区域销售额) plt.xlabel(区域) plt.ylabel(销售额) plt.tight_layout() plt.savefig(output/sales_by_region.png, dpi150)折线图适合看趋势。按月份看销售额monthly df.groupby(df[date].dt.to_period(M))[销售额].sum() monthly.index monthly.index.astype(str) plt.plot(monthly.index, monthly.values, markero) plt.title(月度销售额趋势) plt.xlabel(月份) plt.ylabel(销售额) plt.show()饼图适合看占比但不适合分类太多的情况category_sales df.groupby(category)[销售额].sum() plt.pie(category_sales.values, labelscategory_sales.index, autopct%.1f%%, startangle90) plt.axis(equal) plt.show()autopct控制百分比显示格式startangle控制起始角度。饼图一定要配合axis(equal)否则圆形会变成椭圆。散点图适合看两个数值变量之间的关系比如数量和利润是否相关plt.scatter(df[quantity], df[利润], alpha0.6) plt.xlabel(数量) plt.ylabel(利润) plt.show()alpha控制透明度点重叠时能看到密度差异。6.3 中文乱码与字体设置Matplotlib 默认字体不含中文字符直接画中文标题会显示成方框。解决方案是先指定中文字体plt.rcParams[font.sans-serif] [Microsoft YaHei, SimHei, PingFang SC] plt.rcParams[axes.unicode_minus] FalseMicrosoft YaHei是 Windows 常见字体SimHei也是常见中文字体PingFang SC是 macOS 字体。axes.unicode_minus False用来解决负号显示为方块的问题。如果系统里没有这些字体可以改用英文标签或在 Matplotlib 配置中指定已安装的字体文件路径。检查当前可用字体import matplotlib.font_manager as fm fonts [f.name for f in fm.fontManager.ttflist] print(Microsoft YaHei in fonts)常见坑是只设置rcParams[font.sans-serif]但没有删除缓存。修改字体后最好重启 Python 进程或者删除~/.matplotlib下的字体缓存目录。7. 运行验证与结果分析写完代码后不能只看“程序不报错”还要确认结果在业务上是否正确。这一步是很多人忽略的。7.1 完整脚本运行预期输出合并前面内容后脚本会输出如下信息订单总数: 10 总销售额: 6686 商品销售排行: 27寸显示器 3996 USB扩展坞 903 机械键盘 897 无线鼠标 890 各区域销售额: 华东 2279 华北 2146 华南 1775数字来自前面 CSV 的手工计算。可以看到显示器单价高、数量少但总销售额最高外设类商品订单多但总销售额并不一定最高。7.2 如何确认结论正确验证分为三层代码层对比df[销售额].sum()是否等于df[quantity].sum() * df[unit_price].sum()的错误想法这里要用(df[quantity] * df[unit_price]).sum()因为不同商品单价不同。数据层手工筛选几行用计算器复核确保没有选错行。业务层结论是否符合常识比如显示器数量少但价格高销售额高是合理的。如果发现groupby的结果比预期多先检查是否有重复product名称比如“无线鼠标 ”和“无线鼠标”是两个不同值。这类问题用df[product].value_counts()一眼就能看出来。7.3 图表验证图片不是生成出来就结束。保存图片后要检查三件事标题是否完整中文是否乱码。X 轴和 Y 轴标签是否准确单位是否清楚。柱子排序是否合理饼图比例是否符合表格数字。推荐把图表统一导出到output目录使用dpi150以上保证清晰度plt.savefig(output/sales_by_region.png, dpi150, bbox_inchestight)bbox_inchestight会自动裁剪空白区域避免标题被截断。8. 常见问题排查实际运行中几乎每个人都会遇到下面几类问题。这里按“现象、原因、检查、解决”的顺序给出排查路径。8.1 报错 ModuleNotFoundError现象import numpy时报ModuleNotFoundError: No module named numpy。检查方式which python python -m pip list原因通常是当前终端激活的 Python 环境里没有安装该库或者安装到了另一个 Python 版本。解决方式python -m pip install numpy pandas matplotlib先确认which python指向的解释器再用python -m pip而不是裸pip可以避免安装到错误环境。常见坑是直接执行pip install numpy但系统里同时存在多个 Python结果库装到了旧版本里。8.2 模块可以导入但版本冲突现象import pandas成功但执行pd.to_datetime时出现ValueError或TypeError。原因Pandas 和 NumPy 版本不匹配或者代码使用了当前版本不支持的写法。检查方式print(pandas.__version__) print(numpy.__version__)解决方式在项目目录生成requirements.txt固定版本范围numpy1.24,3 pandas2.0,3 matplotlib3.7然后执行pip install -r requirements.txt。不建议盲目升级到最新版新版本发布初期可能还未适配其他库。8.3 中文显示为方块现象图表标题和坐标轴标签是方框或乱码。原因Matplotlib 默认字体不含中文字符。检查方式import matplotlib.font_manager as fm print(any(Hei in f.name for f in fm.fontManager.ttflist))解决方式plt.rcParams[font.sans-serif] [Microsoft YaHei, SimHei, PingFang SC] plt.rcParams[axes.unicode_minus] False如果设置了仍无效删除字体缓存目录后重启进程。生产环境中如果在 Linux 服务器上绘图需要先安装中文字体例如fonts-noto-cjk否则中文字体列表里没有候选字体。8.4 Pandas 切片赋值警告现象执行类似df[df[销量] 100][备注] 高时出现SettingWithCopyWarning。原因链式赋值可能修改的是视图而非原数据Pandas 无法确定你的意图。检查方式查看代码中是否连续出现了两次方括号索引。解决方式统一使用.locdf.loc[df[销量] 100, 备注] 高在较新版本中Pandas 会逐步收紧这类行为所以不要在零基础阶段养成链式赋值的习惯。先复制再修改或直接用.loc。8.5 CSV 路径找不到现象FileNotFoundError: [Errno 2] No such file or directory: data/orders.csv。原因脚本启动目录和文件相对路径不一致。解决方式from pathlib import Path BASE_DIR Path(__file__).resolve().parent df pd.read_csv(BASE_DIR / data / orders.csv)排查这类问题第一步永远先打印当前路径import os print(os.getcwd())8.6 坐标轴比例变形现象画圆形时显示为椭圆画地图时角度失真。原因未设置坐标轴比例。解决方式ax.set_aspect(equal)排查时先看是否只有一个子图再确认是否在正确的Axes对象上调用。如果同时使用多个子图每个ax都要单独设置。9. 最佳实践与扩展方向9.1 学习环境和生产环境差异学习阶段只要能跑通示例即可生产环境需要额外考虑项目学习环境生产环境数据文件本地 CSV数据库、数仓、对象存储代码组织单脚本模块化、函数化、配置外置日志printlogging 结构化日志错误处理报错后手动改异常捕获、告警、重试图表直接显示保存到对象存储或报表平台性能小数据分片、向量化、并行或 Spark版本管理手动记录lock 文件、容器镜像生产环境不要依赖交互式绘图要使用savefig输出文件不要把 CSV 路径硬编码要用环境变量或配置文件不要忽略异常要记录日志并设置可观测指标。9.2 可复用检查清单每次完成一个数据分析任务可以按下面清单自检环境是否一致记录 Python 版本和库版本。数据是否读取成功核对行数、列名、字段类型。缺失值是否处理明确删除还是填充填充值是否合理。日期类型是否正确确认dtype是 datetime 而非 object。分组结果是否遗漏检查groupby字段是否有空值或大小写差异。金额计算是否准确统一计算逻辑避免浮点数误差影响最终展示。图表是否可读标题、标签、刻度、单位、中文是否正常。结果是否可复现固定随机种子、固定依赖版本、保留原始数据。9.3 下一步学习路径学完三件套后可以根据方向选择扩展数据读取与库交互学习 SQL用 Pandas 连接 PostgreSQL 或 MySQL。更复杂的表格逻辑学习pivot_table、melt、窗口函数。数据可视化进阶学习 Seaborn 或 Plotly前者适合统计图表后者适合交互图表。自动化报表用 Jupyter Notebook 整理分析流程或把脚本部署为定时任务。机器学习入门在 Pandas 清洗完数据后用 scikit-learn 完成分类或回归任务。零基础阶段最重要的事情是保持“数据、代码、输出”三者对应。学一个函数时先看它接收什么、输出什么、在哪个阶段使用。能把订单数据从 CSV 清洗成表格、算清销售额、画出一张可信图表就已经跨越了从语法到实战的边界。后面的高级技巧都是在同一套流程上加更多工具。