大家好,我是专注于Python数据分析实战的博主。很多同学在学习数据分析时,常常感觉理论枯燥,找不到能串联起Pandas、Matplotlib等核心库的完整项目。今天,我们就通过一个非常贴近生活的实战案例——家庭用电数据分析,来手把手带你走完一个数据分析项目的全流程。从数据获取、清洗、探索性分析(EDA)到可视化呈现,最后生成一份完整的分析报告。学完这个项目,你不仅能掌握数据分析的核心技能链,更能将这套方法论应用到任何业务场景中,为你的简历增添一个亮眼的实战项目。
1. 项目背景与核心概念
1.1 什么是家庭用电数据分析?
家庭用电数据分析,是指收集家庭在特定时间段内的用电量数据,并运用数据分析方法,从中挖掘用电模式、识别异常、评估能效,并最终为节能降耗或费用优化提供决策支持的过程。这本质上是一个时间序列数据分析的经典场景。
1.2 为什么选择这个项目?
- 数据贴近生活,易于理解:用电数据(时间、用量)直观,分析结论(如“晚上8点是用电高峰”)容易产生共鸣,学习曲线平缓。
- 技术栈全面:本项目将覆盖数据分析的完整流程,涉及
Pandas数据处理、Matplotlib/Seaborn可视化、NumPy计算以及Jupyter Notebook的使用,是检验和巩固Python数据分析能力的绝佳试金石。 - 具备商业价值延伸:其方法论可直接迁移到商业领域,如零售业的销售额分析、互联网产品的用户活跃度分析、物联网设备的监控数据分析等。
- 结果可交付:最终能生成直观的图表和数据分析报告,形成一个有头有尾、拿得出手的作品。
1.3 我们将分析什么?
我们将模拟分析一个家庭一年的用电数据,主要围绕以下几个核心问题展开:
- 整体趋势:全年用电量是上升、下降还是保持稳定?是否存在季节性规律?
- 周期性规律:用电量在一天内(小时)、一周内(星期几)有何规律?
- 极值与异常:用电高峰和低谷出现在什么时候?是否存在异常用电日?
- 能耗评估:能否通过分析,给出合理的节能建议?
2. 环境准备与工具说明
工欲善其事,必先利其器。以下是完成本项目所需的软件环境与Python库。建议使用Anaconda来管理环境,它能一站式解决大部分依赖问题。
2.1 基础环境
- 操作系统:Windows 10/11, macOS, 或 Linux (如Ubuntu) 均可。
- Python版本:>= 3.8 (推荐3.9或3.10,兼容性和稳定性更好)。
- 开发工具:Jupyter Notebook或Jupyter Lab。它们非常适合交互式数据分析和可视化,是数据分析师的标准工具。
- 代码编辑器:VS Code 或 PyCharm (用于编写和调试较复杂的脚本)。
2.2 必需Python库
我们将通过pip安装以下核心库。请在你的命令行终端中执行安装命令。
# 如果网络较慢,可以使用清华镜像源:-i https://pypi.tuna.tsinghua.edu.cn/simple pip install pandas numpy matplotlib seaborn jupyter- pandas:数据分析的核心,用于数据加载、清洗、转换和聚合。
- numpy:提供高性能的数组运算,是pandas的底层基础。
- matplotlib:最基础的绘图库,高度可定制化。
- seaborn:基于matplotlib,提供了更美观、更高级的统计图表接口,默认样式更好看。
- jupyter:用于启动Notebook交互式环境。
2.3 创建项目结构
建议建立如下清晰的项目目录,养成良好的工程习惯。
family_power_analysis/ │ ├── data/ # 存放数据文件 │ └── household_power_consumption.csv ├── notebooks/ # 存放Jupyter Notebook分析文件 │ └── 01_eda_visualization.ipynb ├── src/ # 存放可重用的Python脚本 │ ├── data_loader.py │ └── visualization.py ├── output/ # 存放生成的图表和分析报告 │ ├── figures/ │ └── report.md └── requirements.txt # 项目依赖列表你可以在项目根目录下创建requirements.txt文件,内容如下:
pandas>=1.4.0 numpy>=1.22.0 matplotlib>=3.5.0 seaborn>=0.11.0 jupyter>=1.0.0然后使用pip install -r requirements.txt一键安装所有依赖。
3. 数据理解与加载
3.1 数据源说明
本教程使用一个广泛用于教学的公开数据集(经过改编以适应家庭场景)。该数据集包含以下字段:
date: 日期,格式为 YYYY-MM-DD。time: 时间,格式为 HH:MM:SS。global_active_power: 家庭全局有功功率(千瓦)。这是我们分析的主要指标,可以近似理解为瞬时用电功率。global_reactive_power: 全局无功功率(千瓦)。voltage: 电压(伏特)。global_intensity: 全局电流强度(安培)。sub_metering_1: 厨房用电量(瓦时)。sub_metering_2: 洗衣房用电量(瓦时)。sub_metering_3: 空调与热水器用电量(瓦时)。
核心关系:global_active_power* 时间 = 用电量。我们通常更关注global_active_power的走势和统计值。
3.2 使用Pandas加载数据
首先,启动Jupyter Notebook,在notebooks目录下新建一个名为01_eda_visualization.ipynb的文件。
第一步,导入必要的库并加载数据。
# 导入必要的库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datetime import datetime # 设置绘图风格,让图表更美观 plt.style.use('seaborn-v0_8-darkgrid') # 使用seaborn的网格风格 sns.set_palette("husl") # 设置颜色盘 %matplotlib inline # 在Notebook中直接显示图表 # 加载数据 # 假设数据文件放在上一级目录的data文件夹中 file_path = '../data/household_power_consumption.csv' # 使用pandas的read_csv函数,这是最常用的数据读取方法 df = pd.read_csv(file_path) # 查看数据前5行,了解数据结构 print("数据形状(行数, 列数):", df.shape) df.head()运行后,你会看到数据的前几行,确认数据已成功加载。
3.3 初步数据探索
在清洗之前,我们需要对数据有一个整体的认识。
# 1. 查看数据基本信息 print("=== 数据基本信息 ===") df.info() # 显示每列的非空值数量、数据类型 # 2. 查看数值型数据的统计摘要 print("\n=== 数值型数据统计摘要 ===") print(df.describe()) # 3. 检查缺失值 print("\n=== 缺失值统计 ===") missing_values = df.isnull().sum() print(missing_values[missing_values > 0]) # 只显示有缺失值的列df.info()会告诉你是否有缺失值(Non-Null Count小于总行数)以及每列的数据类型。df.describe()会展示数值列的平均值、标准差、最小值、分位数和最大值,这对于发现异常值(比如功率为负数或极大值)非常有用。
4. 数据清洗与预处理
原始数据几乎不可能完美,清洗是数据分析中最关键也最耗时的一步。
4.1 处理缺失值
根据上一步的缺失值检查结果,我们采取相应策略。常见方法有:
- 删除:如果缺失行很少,且随机分布,可以直接删除。
- 填充:用平均值、中位数、众数或前后值填充。
- 插值:对于时间序列数据,使用时间插值法。
# 假设我们发现`global_active_power`有少量缺失 # 方法1:删除含有缺失值的行(如果缺失很少) # df_cleaned = df.dropna(subset=['global_active_power']) # 方法2:使用前一行的值进行填充(适用于时间序列) df['global_active_power'] = df['global_active_power'].fillna(method='ffill') # 再次检查缺失值 print("填充后缺失值数量:", df['global_active_power'].isnull().sum())4.2 处理日期和时间列
为了便于按时间维度分析,我们需要将date和time列合并,并转换为Pandas的datetime类型。
# 合并日期和时间列,创建新的`datetime`列 df['datetime'] = pd.to_datetime(df['date'] + ' ' + df['time']) # 将新的datetime列设置为数据框的索引,这是时间序列分析的常用操作 df.set_index('datetime', inplace=True) # 现在可以方便地按时间筛选了 # 例如,查看2025年7月的数据 # july_2025_data = df['2025-07'] # 提取有用的时间特征,供后续分析 df['hour'] = df.index.hour df['day_of_week'] = df.index.dayofweek # 周一=0, 周日=6 df['month'] = df.index.month df['year'] = df.index.year # 删除原始的日期和时间列,避免重复 df.drop(['date', 'time'], axis=1, inplace=True) # 查看处理后的数据前几行 df.head()4.3 处理异常值
异常值可能源于记录错误或特殊事件(如家庭聚会)。我们可以用统计方法(如IQR法则)或业务规则来识别。
# 使用箱线图原理(IQR)检测`global_active_power`的异常值 Q1 = df['global_active_power'].quantile(0.25) Q3 = df['global_active_power'].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR # 标记异常值 outliers = df[(df['global_active_power'] < lower_bound) | (df['global_active_power'] > upper_bound)] print(f"疑似异常值数量: {len(outliers)}") print(f"占总数据比例: {len(outliers)/len(df)*100:.2f}%") # 决策:根据比例决定处理方式 # 如果比例很小(如<1%),可以考虑删除或视为特殊事件保留 # 这里我们选择保留,但记录下来 df['is_outlier'] = False df.loc[outliers.index, 'is_outlier'] = True5. 探索性数据分析与可视化
数据清洗完毕后,就进入了最有趣的环节——探索性数据分析。我们将通过可视化来发现数据中的模式和规律。
5.1 整体用电趋势分析
首先,我们看看全年的用电功率趋势。由于数据量可能很大,我们可以按天进行重采样聚合。
# 按天计算平均有功功率 daily_power = df['global_active_power'].resample('D').mean() # 绘制全年趋势图 plt.figure(figsize=(16, 6)) plt.plot(daily_power.index, daily_power.values, linewidth=1) plt.title('家庭日均有功功率趋势(全年)', fontsize=15) plt.xlabel('日期') plt.ylabel('平均有功功率 (千瓦)') plt.grid(True, alpha=0.3) # 添加月度分隔线,便于观察季节性 for month in range(1, 13): plt.axvline(pd.Timestamp(f'{df.index.year[0]}-{month:02d}-01'), color='gray', linestyle='--', alpha=0.5) plt.tight_layout() plt.savefig('../output/figures/yearly_trend.png', dpi=300, bbox_inches='tight') plt.show()分析要点:观察曲线是否有明显的上升/下降趋势?夏季(6-8月)和冬季(12-2月)的用电量是否更高?这可能与空调和供暖设备的使用有关。
5.2 日内用电模式分析(小时级)
家庭用电在一天内通常有固定的模式,比如早晚高峰。
# 按小时计算所有日期的平均功率 hourly_pattern = df.groupby('hour')['global_active_power'].mean() plt.figure(figsize=(12, 6)) # 使用柱状图更直观 plt.bar(hourly_pattern.index, hourly_pattern.values, color='skyblue', edgecolor='black') plt.title('家庭平均日内用电模式(按小时)', fontsize=15) plt.xlabel('一天中的小时 (0-23)') plt.ylabel('平均有功功率 (千瓦)') plt.xticks(range(0, 24)) plt.grid(axis='y', alpha=0.3) # 标记典型时段 plt.axvspan(7, 9, alpha=0.2, color='orange', label='早晨高峰') plt.axvspan(18, 22, alpha=0.2, color='red', label='晚间高峰') plt.legend() plt.tight_layout() plt.savefig('../output/figures/daily_pattern.png', dpi=300) plt.show()分析要点:通常会出现两个高峰:早晨(7-9点,起床准备)和晚间(18-22点,下班回家、做饭、娱乐)。夜间(0-6点)用电量最低。这个模式是否符合你的预期?
5.3 周内用电模式分析(星期级)
分析一周中哪几天用电最多。
# 按星期几计算平均功率 weekday_pattern = df.groupby('day_of_week')['global_active_power'].mean() weekday_names = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] plt.figure(figsize=(10, 6)) plt.plot(weekday_names, weekday_pattern.values, marker='o', linewidth=2, markersize=8) plt.title('家庭平均周内用电模式', fontsize=15) plt.xlabel('星期') plt.ylabel('平均有功功率 (千瓦)') plt.grid(True, alpha=0.3) plt.fill_between(weekday_names, weekday_pattern.values, alpha=0.2) plt.tight_layout() plt.savefig('../output/figures/weekly_pattern.png', dpi=300) plt.show()分析要点:周末(周六、日)的用电量是否明显高于工作日?这可能是因为家庭成员全天在家,使用了更多电器。
5.4 用电量分布与相关性分析
了解用电功率的分布情况,以及不同子计量表(厨房、洗衣房等)与总用电的关系。
fig, axes = plt.subplots(2, 2, figsize=(14, 10)) # 1. 全局有功功率分布直方图 axes[0, 0].hist(df['global_active_power'], bins=50, edgecolor='black', alpha=0.7) axes[0, 0].set_title('全局有功功率分布') axes[0, 0].set_xlabel('有功功率 (千瓦)') axes[0, 0].set_ylabel('频次') axes[0, 0].axvline(df['global_active_power'].mean(), color='red', linestyle='--', label=f'均值: {df["global_active_power"].mean():.2f}') axes[0, 0].legend() # 2. 三个子计量表的箱线图 sub_meter_cols = ['sub_metering_1', 'sub_metering_2', 'sub_metering_3'] df[sub_meter_cols].plot(kind='box', ax=axes[0, 1]) axes[0, 1].set_title('子计量表用电量分布(箱线图)') axes[0, 1].set_ylabel('用电量 (瓦时)') # 3. 子计量表与总有功功率的散点图(示例:厨房) axes[1, 0].scatter(df['sub_metering_1'], df['global_active_power'], alpha=0.5, s=1) axes[1, 0].set_title('厨房用电 vs 总有功功率') axes[1, 0].set_xlabel('厨房用电量 (瓦时)') axes[1, 0].set_ylabel('总有功功率 (千瓦)') # 4. 计算并绘制相关性热力图 correlation_matrix = df[['global_active_power', 'global_reactive_power', 'voltage', 'global_intensity'] + sub_meter_cols].corr() sns.heatmap(correlation_matrix, annot=True, fmt='.2f', cmap='coolwarm', center=0, ax=axes[1, 1]) axes[1, 1].set_title('特征间相关性热力图') plt.tight_layout() plt.savefig('../output/figures/distribution_correlation.png', dpi=300) plt.show()分析要点:
- 直方图:看功率主要集中在哪个区间,分布是否对称。
- 箱线图:比较不同区域(厨房、洗衣房、空调)用电量的中位数、离散程度和异常值。
- 散点图:观察某个子项(如厨房)用电增加时,总功率是否线性增加。
- 热力图:
global_intensity(电流)和global_active_power(功率)理论上应高度正相关,可以从图中验证。电压与功率的相关性可能较弱。
6. 深入洞察与特征工程
基于基础分析,我们可以提出更深入的问题,并创建新的特征来寻找答案。
6.1 识别用电高峰日
哪些日子用电异常高?可能是节假日、家庭聚会或极端天气。
# 找出日均功率最高的10天 top_10_days = daily_power.nlargest(10) print("用电量最高的10天:") print(top_10_days) # 可视化 plt.figure(figsize=(12, 6)) plt.bar(range(len(top_10_days)), top_10_days.values, color='coral') plt.title('家庭用电量最高的10个日子', fontsize=15) plt.xlabel('排名') plt.ylabel('日均有功功率 (千瓦)') plt.xticks(range(len(top_10_days)), [d.strftime('%Y-%m-%d') for d in top_10_days.index], rotation=45) plt.grid(axis='y', alpha=0.3) plt.tight_layout() plt.savefig('../output/figures/top_10_days.png', dpi=300) plt.show()行动:对照日历,检查这些日期是否是公共假期、周末或特殊天气日(极热或极冷),这能验证你的假设。
6.2 创建用电“峰谷平”时段特征
这对于分时电价策略或智能家居自动化很有用。我们可以根据小时级模式,定义时段。
# 基于之前的hourly_pattern,定义时段 def define_time_period(hour): if 0 <= hour < 6: return '低谷' elif 6 <= hour < 9: return '早高峰' elif 9 <= hour < 17: return '平段' elif 17 <= hour < 22: return '晚高峰' else: # 22-24点 return '低谷' df['time_period'] = df['hour'].apply(define_time_period) # 统计各时段的用电量占比(这里用功率均值近似) period_power = df.groupby('time_period')['global_active_power'].mean().sort_values(ascending=False) print("各时段平均用电功率:") print(period_power) # 绘制饼图 plt.figure(figsize=(8, 8)) plt.pie(period_power.values, labels=period_power.index, autopct='%1.1f%%', startangle=90, colors=sns.color_palette('pastel')) plt.title('家庭用电功率时段分布') plt.tight_layout() plt.savefig('../output/figures/time_period_pie.png', dpi=300) plt.show()6.3 分析不同季节的用电模式
将数据按季节划分,比较用电习惯的变化。
# 定义季节函数 def get_season(month): if month in [12, 1, 2]: return '冬季' elif month in [3, 4, 5]: return '春季' elif month in [6, 7, 8]: return '夏季' else: # 9, 10, 11 return '秋季' df['season'] = df['month'].apply(get_season) # 按季节和小时聚合,绘制多线图 seasonal_hourly = df.groupby(['season', 'hour'])['global_active_power'].mean().unstack(level=0) plt.figure(figsize=(14, 7)) for season in seasonal_hourly.columns: plt.plot(seasonal_hourly.index, seasonal_hourly[season], marker='o', label=season, linewidth=2) plt.title('不同季节的日内用电模式对比', fontsize=15) plt.xlabel('小时') plt.ylabel('平均有功功率 (千瓦)') plt.xticks(range(0, 24)) plt.grid(True, alpha=0.3) plt.legend(title='季节') plt.tight_layout() plt.savefig('../output/figures/seasonal_pattern.png', dpi=300) plt.show()分析要点:夏季的晚间高峰是否更突出(空调)?冬季的早晨和夜间用电是否更高(供暖)?这个分析能直接关联到具体的电器使用行为。
7. 生成分析报告与总结
数据分析的最终目的是形成结论和建议。我们可以将关键发现整理成一份简单的报告。
7.1 核心发现总结
基于以上分析,我们可以总结出以下几点核心发现:
- 整体趋势:全年用电存在季节性波动,夏季和冬季为用电高峰,春秋季相对较低。
- 日内规律:用电呈现典型的“双峰”模式,早高峰(7-9点)和晚高峰(18-22点)明显,夜间用电量最低。
- 周内规律:周末(周六、日)的平均用电量高于工作日,符合家庭活动规律。
- 用电构成:空调/热水器(
sub_metering_3)的用电量波动最大,是总用电量的主要贡献者和可变因素。 - 异常日期:用电量最高的日期多集中在夏季最热的几天和冬季最冷的几天,以及个别节假日。
7.2 节能建议
基于数据洞察,可以提出数据驱动的节能建议:
- 针对晚高峰:晚高峰(18-22点)是用电最集中的时段,也是电网负荷最重的时候。建议将部分高耗能活动(如使用洗衣机、洗碗机、给电动汽车充电)调整到夜间低谷时段(0-6点),如果当地实行分时电价,此举还能节省电费。
- 空调/供暖管理:夏季和冬季的用电陡增主要来自温控设备。建议将空调设定温度提高1-2℃(夏季)或降低1-2℃(冬季),并利用智能温控器在夜间或离家时自动调节。
- 待机功耗:即使夜间,仍存在基础用电。检查并关闭不必要电器的待机电源(如机顶盒、电脑显示器、充电器),可能带来长期节省。
7.3 生成简易文本报告
我们可以用Python将关键指标和结论自动写入一个Markdown文件。
# 将关键指标计算出来 report_data = { "全年平均功率 (kW)": f"{df['global_active_power'].mean():.3f}", "全年最大功率 (kW)": f"{df['global_active_power'].max():.3f}", "用电最高日": f"{top_10_days.index[0].strftime('%Y-%m-%d')} ({top_10_days.iloc[0]:.3f} kW)", "早高峰时段": "07:00 - 09:00", "晚高峰时段": "18:00 - 22:00", "用电最多季节": df.groupby('season')['global_active_power'].mean().idxmax(), "用电最少季节": df.groupby('season')['global_active_power'].mean().idxmin(), } # 生成Markdown报告 report_content = f"""# 家庭用电数据分析报告 ## 概述 本报告基于{len(df)}条用电记录数据,分析了家庭在一年内的用电行为模式。 ## 关键指标 """ for key, value in report_data.items(): report_content += f"- **{key}**: {value}\n" report_content += """ ## 主要发现 1. **季节性波动明显**:夏季和冬季是用电高峰期,空调和供暖设备是主要因素。 2. **日内双峰模式**:用电集中在早晚两个高峰时段,符合家庭作息规律。 3. **周末用电量更高**:家庭成员全天在家导致周末用电量较工作日提升约15%。 4. **存在可优化空间**:晚高峰用电过于集中,部分高耗能电器可移至谷电时段使用。 ## 建议 - **错峰用电**:充分利用夜间低谷时段进行洗衣、充电等活动。 - **智能温控**:对空调、热水器等设备进行精细化温度与时间管理。 - **设备检查**:关注待机功耗,更换老旧高耗能电器。 """ # 保存报告 report_path = '../output/report.md' with open(report_path, 'w', encoding='utf-8') as f: f.write(report_content) print(f"分析报告已生成至: {report_path}")8. 常见问题与排查思路
在实际操作中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
ImportError: No module named 'pandas' | Python环境未安装所需库。 | 在终端使用pip install pandas numpy matplotlib seaborn安装。如果使用Anaconda,可用conda install。 |
FileNotFoundError当读取CSV文件时 | 文件路径错误或文件不存在。 | 使用import os; print(os.path.abspath('.'))查看当前工作目录。使用绝对路径或相对于当前脚本的正确相对路径。 |
| 图表中文显示为方框(乱码) | Matplotlib默认字体不包含中文。 | 在导入matplotlib后添加以下代码:plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']plt.rcParams['axes.unicode_minus'] = False(需系统有相应中文字体) |
| 数据加载慢,内存占用高 | CSV文件过大(几百MB以上)。 | 1. 使用pd.read_csv(file_path, usecols=[...])只读取需要的列。2. 指定数据类型 dtype。3. 分块读取 chunksize。 |
KeyError当访问不存在的列时 | 列名拼写错误或确实不存在。 | 使用df.columns打印所有列名,仔细核对。列名区分大小写和空格。 |
| 时间序列绘图时X轴标签重叠 | 时间数据点过于密集。 | 1. 对数据重采样(如.resample('D').mean())降低密度。2. 使用 plt.xticks(rotation=45)旋转标签。3. 使用 fig.autofmt_xdate()自动调整。 |
SettingWithCopyWarning警告 | 对DataFrame切片进行赋值操作,链式索引可能引起歧义。 | 使用.loc或.iloc进行明确索引赋值。例如:df.loc[mask, 'new_col'] = value。 |
9. 最佳实践与项目扩展建议
完成基础分析后,你可以从以下方向深化这个项目,使其更具竞争力。
9.1 代码组织最佳实践
- 模块化:将数据加载、清洗、可视化函数分别写入
src/目录下的.py文件(如data_loader.py,visualization.py),然后在Notebook中导入。这使代码更易复用和维护。 - 配置化:将文件路径、颜色方案、时段定义等参数提取到配置文件(如
config.yaml)或字典中,避免硬编码。 - 注释与文档:为每个函数和复杂逻辑块添加清晰的注释。使用文档字符串(
""")说明函数用途、参数和返回值。
9.2 分析深度扩展
- 预测模型:使用时间序列模型(如ARIMA、Prophet或LSTM)预测未来用电量。这是数据分析师/科学家岗位的常见技能要求。
- 异常检测:使用统计方法(如Z-score)或机器学习算法(如Isolation Forest)自动检测异常用电日,用于防盗或设备故障预警。
- 聚类分析:对每天的用电曲线进行聚类,发现不同的家庭活动模式(如工作日模式、周末模式、度假模式)。
- 成本计算:结合当地的分时电价表,计算电费总支出,并模拟优化用电时间后的节省效果。
9.3 工程化与部署
- 自动化报告:使用
Jinja2模板库或ReportLab生成更精美的PDF报告,并利用定时任务(如cron或Apache Airflow)每周/每月自动运行分析脚本并发送邮件报告。 - 简易Web应用:使用
Streamlit或Dash框架,快速构建一个交互式仪表盘,让用户上传自己的用电数据并查看分析结果。这是一个展示全栈能力的绝佳项目。 - 数据库集成:将分析结果存储到SQLite或PostgreSQL数据库中,而不是每次都从原始CSV计算。
这个项目从数据到洞察,完整地走了一遍数据分析的标准流程。它不仅让你熟悉了Pandas、Matplotlib等工具,更重要的是培养了用数据解决问题的思维。