简介:这份资源面向希望系统掌握Python数据分析与可视化的学习者,覆盖从编程基础到实战项目的完整技能链路,适合高校学生、转行者及需要处理结构化数据的从业者。压缩包共162个文件,约31.27MB,以67个ipynb实验代码、11个pptx课件、10个csv与6个xls数据集为主,辅以tif、jpg图表素材及doc、pdf教学文档,兼顾理论讲解与动手实践。内容从数据分析与可视化概述切入,依次讲解Python编程基础、pandas统计分析、数据载入与预处理,再深入Matplotlib、Seaborn绘图及pyecharts交互式图表,配套iris、红酒品质、学生成绩等真实数据集,便于边学边练。目前已有18154人学习下载,读者可借助课件、源码与数据集完整复现数据清洗、统计分析与多库可视化流程,积累可迁移的项目经验。1. 从一份 Python 数据分析与可视化源码包说起:它到底能跑出什么如果你手头正好有一份 Python 数据分析与可视化的源码包,第一反应大概率是:先跑起来看看。但真正决定它值不值得留的,不是能不能跑,而是它有没有把「数据清洗 → 特征计算 → 图表输出」这条链路走完整。我见过太多所谓的数据分析项目,打开一看全是pd.read_csv加plt.plot,连缺失值都没处理,这种源码包拿来练手可以,拿去交差就是给自己埋雷。这份资源的核心价值在于,它把数据分析里最容易翻车的几个环节——缺失值填充、分组聚合、时间序列重采样、多子图布局——都落成了可执行的代码,而不是停留在概念层面。适合谁?适合已经会写 Python 基础语法、但一碰到真实脏数据就不知道从哪下手的从业者,也适合需要快速搭一个分析原型、不想从零写模板的人。下面我按「先看懂结构、再动手改、最后避坑」的顺序拆一遍。2. 源码包结构拆解:先搞清楚每个文件在链路里的位置拿到一个源码包,别急着pip install。先花五分钟把目录结构和依赖关系理清楚,能省掉后面一半的报错排查时间。常见的数据分析项目结构不会太复杂,但每个文件都有明确职责,乱改一通只会让问题更难定位。2.1 典型目录布局与文件职责一份合格的 Python 数据分析源码包,通常长这样:project/ ├── data/ │ ├── raw/ # 原始数据,只读不改 │ └── processed/ # 清洗后的中间数据 ├── src/ │ ├── clean.py # 数据清洗:缺失值、异常值、类型转换 │ ├── analyze.py # 统计分析:分组、聚合、透视 │ └── visualize.py # 可视化:图表生成与保存 ├── config.py # 路径、参数、常量集中管理 ├── main.py # 主入口,串联全流程 └── requirements.txt # 依赖清单这个结构的好处是职责分离。clean.py只负责把脏数据变成干净数据,analyze.py只做计算,visualize.py只画图。很多人把所有逻辑塞进一个main.py,跑是能跑,但改一个参数就要翻三百行代码,调试成本极高。config.py是最容易被忽略但最重要的文件。路径、图表尺寸、颜色方案、分组字段名这些都应该集中在这里。我一般会把所有硬编码的字符串和数字都抽出来,后面换数据集时只改这一个文件。2.2 依赖安装与运行入口依赖清单通常包含这几个核心库:# 建议用虚拟环境,避免污染全局 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装依赖 pip install -r requirements.txtrequirements.txt里一般会有pandas、numpy、matplotlib、seaborn,有些还会带scipy或plotly。这里有个细节:如果文件里只写了库名没写版本号,建议手动锁定版本,比如pandas==2.1.0。不同版本的 pandas 在groupby行为和resample参数上有差异,不锁版本很容易出现「我这边能跑你那边报错」的玄学问题。运行入口一般是:python main.py --input data/raw/sample.csv --output data/processed/如果main.py用了argparse,参数说明通常在--help里能看到。先跑一遍--help,比直接读代码快得多。2.3 数据流走向:从原始文件到最终图表理解数据流是改代码的前提。典型链路是这样的:clean.py读取data/raw/下的原始文件,处理缺失值、去重、类型转换,输出到data/processed/analyze.py读取清洗后的数据,做分组聚合、透视表、时间序列计算,返回 DataFramevisualize.py接收分析结果,生成图表并保存到output/或figures/目录# clean.py 中的典型清洗逻辑 import pandas as pd import numpy as np def clean_data(df): # 数值列缺失值用中位数填充,比均值更抗异常值 num_cols = df.select_dtypes(include=[np.number]).columns for col in num_cols: df[col] = df[col].fillna(df[col].median()) # 类别列缺失值用众数填充 cat_cols = df.select_dtypes(include=['object']).columns for col in cat_cols: df[col] = df[col].fillna(df[col].mode()[0]) # 日期列统一转换,errors='coerce' 把无法解析的变成 NaT if 'date' in df.columns: df['date'] = pd.to_datetime(df['date'], errors='coerce') return df这段代码里,fillna(median())而不是mean()是有意的——真实数据里异常值太常见,均值会被拉偏。errors='coerce'是处理日期格式混乱的后悔药,解析不了的直接变NaT,后面可以统一丢弃或填充,不会因为一条脏日期导致整个脚本崩溃。3. 核心分析模块实战:分组聚合、透视表与时间序列清洗完数据只是第一步,真正体现分析价值的是聚合和透视。这部分代码如果写得不规范,后面画出来的图基本没法看。3.1 分组聚合的正确写法与常见参数分组聚合是数据分析里用得最多也最容易写错的操作。先看一段标准写法:# analyze.py 中的分组聚合 def group_analysis(df, group_col, value_col): result = df.groupby(group_col).agg( total=(value_col, 'sum'), # 求和 average=(value_col, 'mean'), # 均值 count=(value_col, 'count'), # 计数 std=(value_col, 'std') # 标准差 ).reset_index() # 按总量降序排列,方便后续图表展示 result = result.sort_values('total', ascending=False) return resultagg里用命名聚合(total=(value_col, 'sum'))比直接传字典更清晰,生成的列名可控。reset_index()不能忘,否则分组字段会变成索引,后面画图时取列名会报KeyError。参数方面,groupby默认dropna=True,如果分组字段有缺失值,这些行会被直接丢掉。如果你希望缺失值也作为一组参与统计,要显式写dropna=False。这个参数在数据质量差的时候影响很大,我一般会先跑一遍df[group_col].isna().sum()看看有多少缺失,再决定要不要保留。3.2 透视表与交叉表:行列维度怎么选透视表适合做二维汇总,比如「各地区 × 各季度」的销售额矩阵:# 透视表:行是地区,列是季度,值是销售额 pivot = pd.pivot_table( df, values='sales', index='region', columns='quarter', aggfunc='sum', fill_value=0, # 缺失组合填 0,避免图表出现空白 margins=True, # 增加合计行列 margins_name='合计' )fill_value=0很关键。透视表默认对不存在的行列组合填NaN,画热力图时会出现白色空洞,填 0 后视觉上更完整。margins=True会自动加一行一列合计,省去手动计算的麻烦。如果只是做频次统计,pd.crosstab更直接:# 交叉表:统计两个类别字段的组合频次 cross = pd.crosstab(df['category'], df['status'], normalize='index')normalize='index'表示按行归一化,输出的是百分比而不是计数。做占比分析时这个参数比手动除法方便得多。3.3 时间序列重采样与滚动窗口时间序列是数据分析里绕不开的场景。重采样(resample)能把不规则的时间数据变成固定频率:# 按周重采样,计算每周的均值和总和 df['date'] = pd.to_datetime(df['date']) df = df.set_index('date') weekly = df.resample('W').agg({ 'value': ['mean', 'sum'], 'count': 'sum' }) # 滚动窗口:7 天移动平均,平滑短期波动 df['ma_7'] = df['value'].rolling(window=7, min_periods=1).mean()resample('W')里的W表示周频,其他常用频率还有D(日)、M(月)、Q(季度)。min_periods=1保证窗口内至少有一个值就计算,否则前 6 天全是NaN,画图时开头会断掉。滚动窗口的window参数决定平滑程度,7 天适合日频数据,30 天适合看长期趋势。窗口越大曲线越平滑,但滞后也越明显,这个取舍要看具体分析目的。4. 可视化模块:从默认图表到可交付的成品图很多人画图就是plt.plot()一把梭,出来的图自己都不想看第二眼。可视化模块的价值在于把图表做成能直接放进报告的程度。4.1 Matplotlib 子图布局与样式统一多子图布局是可视化里最容易翻车的部分。plt.subplots的返回值处理不当,后面设置标签时会各种报错:import matplotlib.pyplot as plt import matplotlib # 设置中文字体,避免中文显示为方块 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams['axes.unicode_minus'] = False fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # axes 是二维数组,用 flat 展平后遍历更安全 for ax, (title, data) in zip(axes.flat, chart_data.items()): ax.plot(data['x'], data['y'], label=title) ax.set_title(title) ax.legend() ax.grid(alpha=0.3) plt.tight_layout() # 自动调整间距,防止标签重叠 plt.savefig('output/dashboard.png', dpi=150, bbox_inches='tight')axes.flat把二维数组展平成一维,遍历时不用管行列索引,代码更简洁。tight_layout()解决子图间距问题,bbox_inches='tight'在保存时裁掉多余白边。dpi=150是报告用图的最低标准,屏幕预览 72 就够,但打印或插入文档至少要 150。4.2 Seaborn 统计图表与配色方案Seaborn 在统计图表上比 Matplotlib 省事得多,尤其是分布图和热力图:import seaborn as sns # 设置整体主题 sns.set_theme(style='whitegrid', palette='muted') # 箱线图:看分布和异常值 fig, ax = plt.subplots(figsize=(10, 6)) sns.boxplot(data=df, x='category', y='value', ax=ax) ax.set_title('各分类数值分布') # 热力图:看相关性矩阵 corr = df.select_dtypes(include='number').corr() sns.heatmap(corr, annot=True, fmt='.2f', cmap='RdBu_r', center=0)palette='muted'是柔和的配色方案,适合正式报告。cmap='RdBu_r'是红蓝发散色,center=0让 0 值对应白色,正负相关一目了然。annot=True在格子里显示数值,fmt='.2f'控制小数位数。4.3 图表保存与输出规范图表保存有几个参数直接影响可用性:# 保存为多种格式 fig.savefig('output/chart.png', dpi=150, bbox_inches='tight', transparent=False) fig.savefig('output/chart.pdf', bbox_inches='tight') # 矢量图,适合论文PNG 适合网页和文档,PDF 是矢量格式,放大不糊,适合印刷。transparent=False保证背景是白色而不是透明,插入 Word 时不会出现黑底。如果图表要给别人改,还可以存一份.svg。5. 避坑与排查:那些让脚本跑不起来的细节这一章是我踩过的坑里挑出来的,每一条都真实发生过,按「现象 → 原因 → 解决」写。5.1 中文显示为方块现象:图表标题和标签里的中文全部变成方块或乱码。原因:Matplotlib 默认字体不支持中文,且axes.unicode_minus默认为True,负号也会显示异常。解决:在绘图前设置matplotlib.rcParams['font.sans-serif'] = ['SimHei']和matplotlib.rcParams['axes.unicode_minus'] = False。如果系统没有 SimHei,换成Microsoft YaHei或WenQuanYi Micro Hei。Linux 环境下需要先确认字体已安装,用fc-list :lang=zh查看可用中文字体。5.2 日期解析失败导致重采样报错现象:resample报TypeError: Only valid with DatetimeIndex。原因:日期列还是字符串类型,没有转成datetime,或者转换时格式不统一产生了NaT。解决:先pd.to_datetime(df['date'], errors='coerce'),然后检查df['date'].isna().sum(),如果缺失太多,需要回头看看原始数据的日期格式。转换后记得set_index('date'),resample只对 DatetimeIndex 生效。5.3 分组聚合后列名变成多级索引现象:groupby().agg()之后,列名变成('value', 'sum')这样的元组,取列时报KeyError。原因:agg传入字典或列表时,pandas 会生成 MultiIndex 列名。解决:用命名聚合agg(total=('value', 'sum'))直接指定单层列名,或者聚合后手动result.columns = ['total', 'average', ...]重命名。命名聚合是更推荐的做法,代码可读性也更好。5.4 透视表 fill_value 没生效现象:设置了fill_value=0,但透视表里还是有NaN。原因:fill_value只填充「行列组合不存在」的格子,如果原始数据里该组合存在但值本身是NaN,不会被填充。解决:先对原始数据的值列做fillna(0),再传给pivot_table。或者在透视表之后用pivot.fillna(0)再补一次。5.5 保存图片时白边过大或标签被裁现象:保存的图片四周有大片白边,或者 x 轴标签被切掉一半。原因:默认保存不会自动调整边界,子图间距也没优化。解决:保存时加bbox_inches='tight',绘图后加plt.tight_layout()。如果标签还是被裁,用plt.subplots_adjust(bottom=0.15)手动留出底部空间。6. 进阶技巧:把分析脚本变成可复用的工具源码包跑通只是起点,真正省时间的是把它改成能反复用的工具。我一般会做三件事:参数化配置、加日志、写一个最小的验证脚本。6.1 用配置文件替代硬编码把所有可变参数抽到config.py或config.yaml:# config.py DATA_PATH = 'data/raw/sample.csv' OUTPUT_DIR = 'output/' GROUP_COL = 'region' VALUE_COL = 'sales' DATE_COL = 'date' FIG_SIZE = (12, 8) DPI = 150换数据集时只改这个文件,不用翻遍所有脚本。如果项目更大,用 YAML 更灵活:import yaml with open('config.yaml', 'r', encoding='utf-8') as f: config = yaml.safe_load(f)6.2 加日志替代 printprint调试在脚本短的时候没问题,但流程一长就失控。用logging模块:import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('run.log', encoding='utf-8'), logging.StreamHandler() ] ) logging.info(f'原始数据形状: {df.shape}') logging.warning(f'缺失值比例: {df.isna().mean().to_dict()}')日志会同时输出到控制台和文件,出问题时翻run.log比在终端里往上滚快得多。6.3 验证脚本:三行代码确认数据没跑偏每次改完清洗逻辑,跑一遍这个检查:def validate(df): assert df.shape[0] > 0, '数据为空' assert df['date'].isna().sum() == 0, '日期列有缺失' assert df['value'].dtype in ['float64', 'int64'], '值列类型不对' print(f'验证通过: {df.shape[0]} 行, {df.shape[1]} 列')assert在条件不满足时直接抛异常,比等到画图时报错更早发现问题。这三个检查覆盖了最常见的翻车点:空数据、日期缺失、类型错误。从那以后我每次拿到新的数据分析源码包,都强制先跑一遍validate,再动任何分析逻辑。这个习惯帮我省掉了至少一半的返工时间。希望这份拆解能帮你把这份 Python 数据分析与可视化资源真正用起来,而不是让它躺在硬盘里吃灰。本文还有配套的精品资源,点击获取
简介:这份资源面向希望系统掌握Python数据分析与可视化的学习者,覆盖从编程基础到实战项目的完整技能链路,适合高校学生、转行者及需要处理结构化数据的从业者。压缩包共162个文件,约31.27MB,以67个ipynb实验代码、11个pptx课件、10个csv与6个xls数据集为主,辅以tif、jpg图表素材及doc、pdf教学文档,兼顾理论讲解与动手实践。内容从数据分析与可视化概述切入,依次讲解Python编程基础、pandas统计分析、数据载入与预处理,再深入Matplotlib、Seaborn绘图及pyecharts交互式图表,配套iris、红酒品质、学生成绩等真实数据集,便于边学边练。目前已有18154人学习下载,读者可借助课件、源码与数据集完整复现数据清洗、统计分析与多库可视化流程,积累可迁移的项目经验。1. 从一份 Python 数据分析与可视化源码包说起:它到底能跑出什么如果你手头正好有一份 Python 数据分析与可视化的源码包,第一反应大概率是:先跑起来看看。但真正决定它值不值得留的,不是能不能跑,而是它有没有把「数据清洗 → 特征计算 → 图表输出」这条链路走完整。我见过太多所谓的数据分析项目,打开一看全是pd.read_csv加plt.plot,连缺失值都没处理,这种源码包拿来练手可以,拿去交差就是给自己埋雷。这份资源的核心价值在于,它把数据分析里最容易翻车的几个环节——缺失值填充、分组聚合、时间序列重采样、多子图布局——都落成了可执行的代码,而不是停留在概念层面。适合谁?适合已经会写 Python 基础语法、但一碰到真实脏数据就不知道从哪下手的从业者,也适合需要快速搭一个分析原型、不想从零写模板的人。下面我按「先看懂结构、再动手改、最后避坑」的顺序拆一遍。2. 源码包结构拆解:先搞清楚每个文件在链路里的位置拿到一个源码包,别急着pip install。先花五分钟把目录结构和依赖关系理清楚,能省掉后面一半的报错排查时间。常见的数据分析项目结构不会太复杂,但每个文件都有明确职责,乱改一通只会让问题更难定位。2.1 典型目录布局与文件职责一份合格的 Python 数据分析源码包,通常长这样:project/ ├── data/ │ ├── raw/ # 原始数据,只读不改 │ └── processed/ # 清洗后的中间数据 ├── src/ │ ├── clean.py # 数据清洗:缺失值、异常值、类型转换 │ ├── analyze.py # 统计分析:分组、聚合、透视 │ └── visualize.py # 可视化:图表生成与保存 ├── config.py # 路径、参数、常量集中管理 ├── main.py # 主入口,串联全流程 └── requirements.txt # 依赖清单这个结构的好处是职责分离。clean.py只负责把脏数据变成干净数据,analyze.py只做计算,visualize.py只画图。很多人把所有逻辑塞进一个main.py,跑是能跑,但改一个参数就要翻三百行代码,调试成本极高。config.py是最容易被忽略但最重要的文件。路径、图表尺寸、颜色方案、分组字段名这些都应该集中在这里。我一般会把所有硬编码的字符串和数字都抽出来,后面换数据集时只改这一个文件。2.2 依赖安装与运行入口依赖清单通常包含这几个核心库:# 建议用虚拟环境,避免污染全局 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装依赖 pip install -r requirements.txtrequirements.txt里一般会有pandas、numpy、matplotlib、seaborn,有些还会带scipy或plotly。这里有个细节:如果文件里只写了库名没写版本号,建议手动锁定版本,比如pandas==2.1.0。不同版本的 pandas 在groupby行为和resample参数上有差异,不锁版本很容易出现「我这边能跑你那边报错」的玄学问题。运行入口一般是:python main.py --input data/raw/sample.csv --output data/processed/如果main.py用了argparse,参数说明通常在--help里能看到。先跑一遍--help,比直接读代码快得多。2.3 数据流走向:从原始文件到最终图表理解数据流是改代码的前提。典型链路是这样的:clean.py读取data/raw/下的原始文件,处理缺失值、去重、类型转换,输出到data/processed/analyze.py读取清洗后的数据,做分组聚合、透视表、时间序列计算,返回 DataFramevisualize.py接收分析结果,生成图表并保存到output/或figures/目录# clean.py 中的典型清洗逻辑 import pandas as pd import numpy as np def clean_data(df): # 数值列缺失值用中位数填充,比均值更抗异常值 num_cols = df.select_dtypes(include=[np.number]).columns for col in num_cols: df[col] = df[col].fillna(df[col].median()) # 类别列缺失值用众数填充 cat_cols = df.select_dtypes(include=['object']).columns for col in cat_cols: df[col] = df[col].fillna(df[col].mode()[0]) # 日期列统一转换,errors='coerce' 把无法解析的变成 NaT if 'date' in df.columns: df['date'] = pd.to_datetime(df['date'], errors='coerce') return df这段代码里,fillna(median())而不是mean()是有意的——真实数据里异常值太常见,均值会被拉偏。errors='coerce'是处理日期格式混乱的后悔药,解析不了的直接变NaT,后面可以统一丢弃或填充,不会因为一条脏日期导致整个脚本崩溃。3. 核心分析模块实战:分组聚合、透视表与时间序列清洗完数据只是第一步,真正体现分析价值的是聚合和透视。这部分代码如果写得不规范,后面画出来的图基本没法看。3.1 分组聚合的正确写法与常见参数分组聚合是数据分析里用得最多也最容易写错的操作。先看一段标准写法:# analyze.py 中的分组聚合 def group_analysis(df, group_col, value_col): result = df.groupby(group_col).agg( total=(value_col, 'sum'), # 求和 average=(value_col, 'mean'), # 均值 count=(value_col, 'count'), # 计数 std=(value_col, 'std') # 标准差 ).reset_index() # 按总量降序排列,方便后续图表展示 result = result.sort_values('total', ascending=False) return resultagg里用命名聚合(total=(value_col, 'sum'))比直接传字典更清晰,生成的列名可控。reset_index()不能忘,否则分组字段会变成索引,后面画图时取列名会报KeyError。参数方面,groupby默认dropna=True,如果分组字段有缺失值,这些行会被直接丢掉。如果你希望缺失值也作为一组参与统计,要显式写dropna=False。这个参数在数据质量差的时候影响很大,我一般会先跑一遍df[group_col].isna().sum()看看有多少缺失,再决定要不要保留。3.2 透视表与交叉表:行列维度怎么选透视表适合做二维汇总,比如「各地区 × 各季度」的销售额矩阵:# 透视表:行是地区,列是季度,值是销售额 pivot = pd.pivot_table( df, values='sales', index='region', columns='quarter', aggfunc='sum', fill_value=0, # 缺失组合填 0,避免图表出现空白 margins=True, # 增加合计行列 margins_name='合计' )fill_value=0很关键。透视表默认对不存在的行列组合填NaN,画热力图时会出现白色空洞,填 0 后视觉上更完整。margins=True会自动加一行一列合计,省去手动计算的麻烦。如果只是做频次统计,pd.crosstab更直接:# 交叉表:统计两个类别字段的组合频次 cross = pd.crosstab(df['category'], df['status'], normalize='index')normalize='index'表示按行归一化,输出的是百分比而不是计数。做占比分析时这个参数比手动除法方便得多。3.3 时间序列重采样与滚动窗口时间序列是数据分析里绕不开的场景。重采样(resample)能把不规则的时间数据变成固定频率:# 按周重采样,计算每周的均值和总和 df['date'] = pd.to_datetime(df['date']) df = df.set_index('date') weekly = df.resample('W').agg({ 'value': ['mean', 'sum'], 'count': 'sum' }) # 滚动窗口:7 天移动平均,平滑短期波动 df['ma_7'] = df['value'].rolling(window=7, min_periods=1).mean()resample('W')里的W表示周频,其他常用频率还有D(日)、M(月)、Q(季度)。min_periods=1保证窗口内至少有一个值就计算,否则前 6 天全是NaN,画图时开头会断掉。滚动窗口的window参数决定平滑程度,7 天适合日频数据,30 天适合看长期趋势。窗口越大曲线越平滑,但滞后也越明显,这个取舍要看具体分析目的。4. 可视化模块:从默认图表到可交付的成品图很多人画图就是plt.plot()一把梭,出来的图自己都不想看第二眼。可视化模块的价值在于把图表做成能直接放进报告的程度。4.1 Matplotlib 子图布局与样式统一多子图布局是可视化里最容易翻车的部分。plt.subplots的返回值处理不当,后面设置标签时会各种报错:import matplotlib.pyplot as plt import matplotlib # 设置中文字体,避免中文显示为方块 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams['axes.unicode_minus'] = False fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # axes 是二维数组,用 flat 展平后遍历更安全 for ax, (title, data) in zip(axes.flat, chart_data.items()): ax.plot(data['x'], data['y'], label=title) ax.set_title(title) ax.legend() ax.grid(alpha=0.3) plt.tight_layout() # 自动调整间距,防止标签重叠 plt.savefig('output/dashboard.png', dpi=150, bbox_inches='tight')axes.flat把二维数组展平成一维,遍历时不用管行列索引,代码更简洁。tight_layout()解决子图间距问题,bbox_inches='tight'在保存时裁掉多余白边。dpi=150是报告用图的最低标准,屏幕预览 72 就够,但打印或插入文档至少要 150。4.2 Seaborn 统计图表与配色方案Seaborn 在统计图表上比 Matplotlib 省事得多,尤其是分布图和热力图:import seaborn as sns # 设置整体主题 sns.set_theme(style='whitegrid', palette='muted') # 箱线图:看分布和异常值 fig, ax = plt.subplots(figsize=(10, 6)) sns.boxplot(data=df, x='category', y='value', ax=ax) ax.set_title('各分类数值分布') # 热力图:看相关性矩阵 corr = df.select_dtypes(include='number').corr() sns.heatmap(corr, annot=True, fmt='.2f', cmap='RdBu_r', center=0)palette='muted'是柔和的配色方案,适合正式报告。cmap='RdBu_r'是红蓝发散色,center=0让 0 值对应白色,正负相关一目了然。annot=True在格子里显示数值,fmt='.2f'控制小数位数。4.3 图表保存与输出规范图表保存有几个参数直接影响可用性:# 保存为多种格式 fig.savefig('output/chart.png', dpi=150, bbox_inches='tight', transparent=False) fig.savefig('output/chart.pdf', bbox_inches='tight') # 矢量图,适合论文PNG 适合网页和文档,PDF 是矢量格式,放大不糊,适合印刷。transparent=False保证背景是白色而不是透明,插入 Word 时不会出现黑底。如果图表要给别人改,还可以存一份.svg。5. 避坑与排查:那些让脚本跑不起来的细节这一章是我踩过的坑里挑出来的,每一条都真实发生过,按「现象 → 原因 → 解决」写。5.1 中文显示为方块现象:图表标题和标签里的中文全部变成方块或乱码。原因:Matplotlib 默认字体不支持中文,且axes.unicode_minus默认为True,负号也会显示异常。解决:在绘图前设置matplotlib.rcParams['font.sans-serif'] = ['SimHei']和matplotlib.rcParams['axes.unicode_minus'] = False。如果系统没有 SimHei,换成Microsoft YaHei或WenQuanYi Micro Hei。Linux 环境下需要先确认字体已安装,用fc-list :lang=zh查看可用中文字体。5.2 日期解析失败导致重采样报错现象:resample报TypeError: Only valid with DatetimeIndex。原因:日期列还是字符串类型,没有转成datetime,或者转换时格式不统一产生了NaT。解决:先pd.to_datetime(df['date'], errors='coerce'),然后检查df['date'].isna().sum(),如果缺失太多,需要回头看看原始数据的日期格式。转换后记得set_index('date'),resample只对 DatetimeIndex 生效。5.3 分组聚合后列名变成多级索引现象:groupby().agg()之后,列名变成('value', 'sum')这样的元组,取列时报KeyError。原因:agg传入字典或列表时,pandas 会生成 MultiIndex 列名。解决:用命名聚合agg(total=('value', 'sum'))直接指定单层列名,或者聚合后手动result.columns = ['total', 'average', ...]重命名。命名聚合是更推荐的做法,代码可读性也更好。5.4 透视表 fill_value 没生效现象:设置了fill_value=0,但透视表里还是有NaN。原因:fill_value只填充「行列组合不存在」的格子,如果原始数据里该组合存在但值本身是NaN,不会被填充。解决:先对原始数据的值列做fillna(0),再传给pivot_table。或者在透视表之后用pivot.fillna(0)再补一次。5.5 保存图片时白边过大或标签被裁现象:保存的图片四周有大片白边,或者 x 轴标签被切掉一半。原因:默认保存不会自动调整边界,子图间距也没优化。解决:保存时加bbox_inches='tight',绘图后加plt.tight_layout()。如果标签还是被裁,用plt.subplots_adjust(bottom=0.15)手动留出底部空间。6. 进阶技巧:把分析脚本变成可复用的工具源码包跑通只是起点,真正省时间的是把它改成能反复用的工具。我一般会做三件事:参数化配置、加日志、写一个最小的验证脚本。6.1 用配置文件替代硬编码把所有可变参数抽到config.py或config.yaml:# config.py DATA_PATH = 'data/raw/sample.csv' OUTPUT_DIR = 'output/' GROUP_COL = 'region' VALUE_COL = 'sales' DATE_COL = 'date' FIG_SIZE = (12, 8) DPI = 150换数据集时只改这个文件,不用翻遍所有脚本。如果项目更大,用 YAML 更灵活:import yaml with open('config.yaml', 'r', encoding='utf-8') as f: config = yaml.safe_load(f)6.2 加日志替代 printprint调试在脚本短的时候没问题,但流程一长就失控。用logging模块:import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('run.log', encoding='utf-8'), logging.StreamHandler() ] ) logging.info(f'原始数据形状: {df.shape}') logging.warning(f'缺失值比例: {df.isna().mean().to_dict()}')日志会同时输出到控制台和文件,出问题时翻run.log比在终端里往上滚快得多。6.3 验证脚本:三行代码确认数据没跑偏每次改完清洗逻辑,跑一遍这个检查:def validate(df): assert df.shape[0] > 0, '数据为空' assert df['date'].isna().sum() == 0, '日期列有缺失' assert df['value'].dtype in ['float64', 'int64'], '值列类型不对' print(f'验证通过: {df.shape[0]} 行, {df.shape[1]} 列')assert在条件不满足时直接抛异常,比等到画图时报错更早发现问题。这三个检查覆盖了最常见的翻车点:空数据、日期缺失、类型错误。从那以后我每次拿到新的数据分析源码包,都强制先跑一遍validate,再动任何分析逻辑。这个习惯帮我省掉了至少一半的返工时间。希望这份拆解能帮你把这份 Python 数据分析与可视化资源真正用起来,而不是让它躺在硬盘里吃灰。本文还有配套的精品资源,点击获取