人人都会AI编程

29.4 数据分析:数据清洗、统计分析、可视化报表

更新时间:2026-07-12

数据分析是一个高度流程化的工作,虽然分析目标千差万别,但核心路径几乎都是:拿数据 → 洗数据 → 做统计 → 画图表 → 写结论。Python 在这个流程里,每一环都有趁手的工具。下面用一个真实的小例子串起整个流程,不讲空泛理论,只讲你真正会用到的操作。

数据清洗:从“脏数据”到可用数据

真实数据通常包含缺失值、异常值、格式混乱、类型错误等问题。数据清洗的目的就是把它们转化为规范、一致、可供分析的结构。

常用库:Pandas

典型清洗步骤(假设我们手头有一个销售记录 sales.csv):

import pandas as pd

# 1. 读取数据
df = pd.read_csv('sales.csv', encoding='utf-8')

# 2. 快速查看数据概况
print(df.head())      # 前5行
print(df.info())      # 列类型、非空数量
print(df.describe())  # 数值列的统计概要

缺失值处理

# 查看缺失情况
print(df.isnull().sum())

# 方法一:直接删除含缺失值的行(适用于缺失比例很小)
df = df.dropna()

# 方法二:填充缺失值 —— 类别型填众数,数值型填均值/中位数
df['类别'] = df['类别'].fillna(df['类别'].mode()[0])
df['金额'] = df['金额'].fillna(df['金额'].median())

格式与类型修正

# 日期列转为 datetime 类型
df['日期'] = pd.to_datetime(df['日期'])

# 价格列去除货币符号、转数值
df['价格'] = df['价格'].str.replace('¥', '').astype(float)

重复值处理

# 删除完全重复的行
df = df.drop_duplicates()

# 按某个键去重,保留第一条
df = df.drop_duplicates(subset='订单号', keep='first')

异常值过滤(简单原则):

# 例如金额必须大于0
df = df[df['金额'] > 0]

# 或者基于分位数过滤极端值
q_low = df['金额'].quantile(0.01)
q_high = df['金额'].quantile(0.99)
df = df[(df['金额'] >= q_low) & (df['金额'] <= q_high)]

清洗完成后,最好将干净数据保存一份,避免重复劳动:

df.to_csv('sales_clean.csv', index=False)

统计分析:挖掘数据背后的规律

清洗之后的数据就可以用来回答业务问题了。Pandas 自带的描述统计、分组聚合功能非常强大。

基础统计

# 数值列的均值、标准差、四分位数
df.describe()

# 单一统计
print(df['金额'].mean())   # 平均销售额
print(df['金额'].sum())    # 总销售额

分组聚合(最实用的分析模式):

# 按类别统计销售额总和与订单数
summary = df.groupby('类别').agg(
    总销售额=('金额', 'sum'),
    平均单价=('金额', 'mean'),
    订单数=('订单号', 'nunique')
).reset_index()
print(summary)

时间序列分析

# 按月统计销售额趋势
df['月份'] = df['日期'].dt.to_period('M')
monthly_sales = df.groupby('月份')['金额'].sum().reset_index()

透视表(类似 Excel 透视表):

# 按类别和地区交叉统计销售额
pivot = pd.pivot_table(df, values='金额', index='类别', columns='地区', aggfunc='sum', fill_value=0)

相关性分析

# 数值列之间的相关系数
corr = df[['金额', '数量', '折扣']].corr()
print(corr)

这些统计结果可以直接输出为 CSV,也可以作为下一步可视化的数据源。

可视化报表:让数据“说话”

统计数字往往不够直观,图表能帮自己和他人快速抓住重点。常用库:Matplotlib(底层绘图)、Seaborn(统计绘图)、以及交互式的 Plotly。

简单趋势图(折线图)

import matplotlib.pyplot as plt

plt.figure(figsize=(10,5))
plt.plot(monthly_sales['月份'].astype(str), monthly_sales['金额'], marker='o')
plt.title('月度销售额趋势')
plt.xlabel('月份')
plt.ylabel('销售额')
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('monthly_sales.png', dpi=150)  # 保存为图片
plt.show()

类别对比(柱状图)

import seaborn as sns

plt.figure(figsize=(8,5))
sns.barplot(data=summary, x='类别', y='总销售额')
plt.title('各类别销售额对比')
plt.tight_layout()
plt.savefig('category_sales.png')
plt.show()

分布直方图

plt.figure(figsize=(8,5))
sns.histplot(df['金额'], bins=30, kde=True)
plt.title('销售额分布')
plt.show()

多维度展示(子图组合)

fig, axes = plt.subplots(1, 2, figsize=(14,5))

# 左图:饼图(各类别销售额占比)
axes[0].pie(summary['总销售额'], labels=summary['类别'], autopct='%1.1f%%')
axes[0].set_title('销售额类别占比')

# 右图:箱线图(按类别金额分布)
sns.boxplot(data=df, x='类别', y='金额', ax=axes[1])
axes[1].set_title('各类别金额分布')

plt.tight_layout()
plt.savefig('dashboard.png')
plt.show()

交互式报表(可选进阶)
用 Plotly 可以生成网页端的交互图表,支持悬停查看数值、缩放等操作,适合分享给非技术的同事。

import plotly.express as px

fig = px.bar(summary, x='类别', y='总销售额', title='各类别销售额',
             hover_data=['订单数', '平均单价'])
fig.write_html('sales_report.html')

落地建议:一个完整分析脚本的骨架

实际工作中,你往往会把以上步骤串成一个自动化脚本,定期(例如每天/每周)运行生成报表。

# 1. 读取与清洗
df = pd.read_csv('sales.csv')
# ... 清洗步骤 ...

# 2. 统计计算
summary = df.groupby('类别')['金额'].sum().reset_index()

# 3. 可视化并保存
plt.figure()
sns.barplot(data=summary, x='类别', y='金额')
plt.title('销售额报告')
plt.savefig('report.png')
print('报表生成完毕')

几个让工作更顺畅的要点

  • Excel 集成:用 df.to_excel('report.xlsx', index=False) 输出 Excel 文件,多数业务方更习惯看 Excel。
  • 中文字体:Matplotlib 默认可能显示中文乱码,加上这两句即可解决(Windows 下):
  plt.rcParams['font.sans-serif'] = ['SimHei']   # 或用 [‘Microsoft YaHei’]
  plt.rcParams['axes.unicode_minus'] = False     # 解决负号显示问题
  
  • 脚本参数化:通过 argparse 传入数据文件路径和输出目录,可复用性更高。

数据分析不是一次性炫技,而是可重复、可交付的流水线。掌握上述模式,你就已经能处理多数业务场景中的“取数-洗数-看数”需求了。