恭喜你!现在你的程序已经能通过网络与外界交互了。但有时候,面对数据库里成百上千条待办记录,你是不是想一眼看出“我最近完成任务的效率是高是低?”“哪个时间段我添加的事项最多?”这些问题的答案,就藏在数据分析与可视化里。
本章我们将学习Python数据分析的两大神器:Pandas(数据处理)和Matplotlib(绘图),以及能生成炫酷交互图表的PyECharts。学完本章,你将能轻松地从数据中提取洞察,并用图表直观地展示出来。
14.1 数据分析概述:从数据到洞察
数据分析就像侦探破案,一般分为几个步骤:
数据获取:从数据库、CSV文件、API等地方拿到原始数据。
数据清洗:处理缺失值、重复值、格式错误等“脏数据”。
数据探索:通过统计、排序、分组等方式初步了解数据特征。
数据可视化:用图表展示规律,让结论一目了然。
得出结论:基于分析做出决策或预测。
今天我们主要聚焦在数据清洗、探索和可视化上,用之前待办事项系统的数据作为素材。
14.2 Pandas入门:Series和DataFrame
Pandas是Python数据分析的核心库,它提供了两种主要的数据结构:
14.2.1 安装与导入
bash
pip install pandas matplotlib pyecharts
python
import pandas as pdimport matplotlib.pyplot as plt# 让图表在Jupyter Notebook中直接显示(如果用Jupyter)# %matplotlib inline
14.2.2 创建DataFrame
我们可以从字典、列表等创建DataFrame。
python
# 从字典创建,键是列名,值是数据列表data ={'姓名':['扣子','小明','小红','小刚'],'年龄':[25,20,22,23],'城市':['北京','上海','广州','深圳']}df = pd.DataFrame(data)print(df)输出:
text
姓名 年龄 城市0 扣子 25 北京1 小明 20 上海2 小红 22 广州3 小刚 23 深圳
14.3 数据加载与探索:从CSV或数据库读取
在实战中,数据通常来自文件或数据库。我们先将待办事项数据库(todos.db)中的数据导出为CSV,或者直接用Pandas连接SQLite。
14.3.1 从CSV读取
假设我们有一个 todos.csv 文件,内容如下(可用之前的数据库导出):
csv
id,content,is_done,created_at1,学习Python,1,2025-01-10 09:002,买牛奶,0,2025-01-11 10:303,写周报,1,2025-01-12 14:154,健身,0,2025-01-13 08:45
读取CSV:
python
df_todos = pd.read_csv('todos.csv')print(df_todos.head())# 查看前5行print(df_todos.info())# 查看数据类型和缺失值print(df_todos.describe())# 查看数值列的统计摘要14.3.2 从SQLite数据库读取
也可以直接用Pandas连接数据库,执行SQL查询:
python
import sqlite3conn = sqlite3.connect('todos.db')df_todos = pd.read_sql_query("SELECT * FROM todos", conn)conn.close()print(df_todos.head())14.4 数据清洗与处理
现实中的数据往往不完美,我们需要清洗。
14.4.1 处理缺失值
假设 created_at 列有缺失值:
python
# 查看缺失值print(df_todos.isnull().sum())# 删除含有缺失值的行df_todos.dropna(inplace=True)# 或者填充缺失值(比如用当前时间填充)df_todos['created_at'].fillna('2025-01-01 00:00', inplace=True)14.4.2 转换数据类型
created_at 通常是字符串,我们应将其转换为时间类型,方便后续按时间分析。
python
df_todos['created_at']= pd.to_datetime(df_todos['created_at'])
14.4.3 添加新列
我们可以提取“日期”和“小时”列:
python
df_todos['日期']= df_todos['created_at'].dt.datedf_todos['小时']= df_todos['created_at'].dt.hour
14.4.4 筛选与排序
python
# 筛选未完成的事项undone = df_todos[df_todos['is_done']==0]print(undone)# 按创建时间排序sorted_df = df_todos.sort_values(by='created_at', ascending=False)
14.4.5 分组聚合
统计每天添加了多少个待办:
python
daily_count = df_todos.groupby('日期').size().reset_index(name='数量')print(daily_count)统计每个小时添加事项的数量:
python
hourly_count = df_todos.groupby('小时').size().reset_index(name='数量')14.5 数据可视化基础:用Matplotlib画图
Matplotlib是最基础的绘图库,上手简单。
14.5.1 折线图:展示趋势
绘制每天事项数量的变化:
python
plt.figure(figsize=(10,5))plt.plot(daily_count['日期'], daily_count['数量'], marker='o')plt.title('每日待办事项添加数量趋势')plt.xlabel('日期')plt.ylabel('数量')plt.xticks(rotation=45)plt.grid(True)plt.show()14.5.2 柱状图:对比分类
绘制每个小时添加事项的数量(假设小时是0-23):
python
plt.figure(figsize=(12,6))plt.bar(hourly_count['小时'], hourly_count['数量'], color='skyblue')plt.title('各小时添加待办事项数量分布')plt.xlabel('小时')plt.ylabel('数量')plt.xticks(range(0,24))plt.show()14.5.3 饼图:查看完成比例
计算已完成和未完成的比例:
python
done_count = df_todos['is_done'].sum()# 1 的数量total =len(df_todos)undone_count = total - done_countplt.figure(figsize=(6,6))plt.pie([done_count, undone_count], labels=['已完成','未完成'], autopct='%1.1f%%', colors=['lightgreen','lightcoral'])plt.title('待办事项完成情况')plt.show()14.6 实战:综合分析待办事项数据
现在我们把上面学到的知识串起来,对真实的待办数据库进行全面分析。
14.6.1 准备工作
从数据库加载数据,并清洗处理:
python
import sqlite3import pandas as pdimport matplotlib.pyplot as plt# 连接数据库conn = sqlite3.connect('todos.db')df = pd.read_sql_query("SELECT * FROM todos", conn)conn.close()# 转换时间列df['created_at']= pd.to_datetime(df['created_at'])# 提取日期和小时df['日期']= df['created_at'].dt.datedf['小时']= df['created_at'].dt.hour# 计算是否完成(is_done已经是0/1)print("数据概览:")print(df.head())print(df.info())14.6.2 分析任务
我们想要回答几个问题:
每天的任务量波动如何?(折线图)
什么时间段最爱添加任务?(柱状图)
任务完成率是多少?(饼图)
任务内容的关键词分布?(需要分词,可选)
14.6.3 绘制图表
python
# 设置中文字体(防止乱码)plt.rcParams['font.sans-serif']=['SimHei']# 或者 ['Arial Unicode MS'] for Macplt.rcParams['axes.unicode_minus']=False# 创建子图布局fig, axes = plt.subplots(2,2, figsize=(14,10))fig.suptitle('待办事项数据分析报告', fontsize=16)# 1. 每日数量趋势daily = df.groupby('日期').size().reset_index(name='数量')axes[0,0].plot(daily['日期'], daily['数量'], marker='o', color='blue')axes[0,0].set_title('每日添加任务数量')axes[0,0].set_xlabel('日期')axes[0,0].set_ylabel('数量')axes[0,0].tick_params(axis='x', rotation=45)# 2. 小时分布hourly = df.groupby('小时').size().reset_index(name='数量')axes[0,1].bar(hourly['小时'], hourly['数量'], color='green', alpha=0.7)axes[0,1].set_title('各小时添加任务分布')axes[0,1].set_xlabel('小时')axes[0,1].set_ylabel('数量')axes[0,1].set_xticks(range(0,24))# 3. 完成比例done_count = df['is_done'].sum()undone_count =len(df)- done_countaxes[1,0].pie([done_count, undone_count], labels=['已完成','未完成'], autopct='%1.1f%%', colors=['lightgreen','lightcoral'])axes[1,0].set_title('任务完成比例')# 4. 统计内容长度分布(或简单词频)df['内容长度']= df['content'].str.len()axes[1,1].hist(df['内容长度'], bins=10, color='orange', alpha=0.7)axes[1,1].set_title('任务内容长度分布')axes[1,1].set_xlabel('字符数')axes[1,1].set_ylabel('数量')plt.tight_layout()plt.show()运行这段代码,你会看到一张包含四个子图的综合报告,直观地展示了待办数据的各种特征。
14.7 用PyECharts制作交互式图表
Matplotlib的图表是静态的,而PyECharts可以生成HTML交互图表,支持鼠标悬停、缩放等。我们来改造一下小时分布的柱状图。
14.7.1 安装与导入
bash
pip install pyecharts
14.7.2 制作交互式柱状图
python
from pyecharts.charts import Barfrom pyecharts import options as opts# 准备数据hours =list(hourly['小时'])counts =list(hourly['数量'])# 创建柱状图bar =( Bar().add_xaxis(hours).add_yaxis("任务数量", counts).set_global_opts( title_opts=opts.TitleOpts(title="各小时添加任务分布(交互式)"), xaxis_opts=opts.AxisOpts(name="小时"), yaxis_opts=opts.AxisOpts(name="数量"),))# 生成HTML文件bar.render("hourly_todos.html")print("已生成交互式图表:hourly_todos.html")运行后,你会在当前目录得到一个HTML文件,用浏览器打开,就能看到可交互的图表啦!
14.8 本章小结
Pandas基础:学会了创建DataFrame、读取CSV/数据库、数据清洗(处理缺失值、类型转换)和分组聚合。
Matplotlib绘图:掌握了折线图、柱状图、饼图和直方图的基本绘制,能将数据转化为直观的图表。
实战应用:成功对自己的待办事项数据进行了多维度分析,并生成了综合报告。
交互式图表:了解了PyECharts,能制作更炫酷的HTML交互图表。
从这一章开始,你不再只是被动地存储和展示数据,而是能主动地从数据中挖掘价值。数据分析能力是Python进阶的重要技能,也是很多高级岗位(如数据分析师、数据科学家)的敲门砖。
✨ 重点回顾
Pandas数据结构:Series(单列)和DataFrame(表格)。
数据清洗三板斧:dropna()/fillna()处理缺失值,astype()/pd.to_datetime()转换类型,groupby()进行分组聚合。
Matplotlib绘图步骤:
数据分析思维:从问题出发,清洗数据→探索规律→可视化呈现→得出结论。
下一章预告:自动化办公与脚本编写
掌握了数据处理和可视化,你可以轻松处理Excel、Word、PDF等办公文档,实现办公自动化。下一章,我们将学习用Python操作常见办公文件,批量处理数据,让你的工作效率翻倍!敬请期待!