Pandas 描述分析和分组分析学习文档

Pandas 描述分析和分组分析学习文档


📚 目录

  1. 环境配置与数据导入
  2. 描述性统计分析
  3. 分组分析
  4. 数据透视表
  5. 交叉表
  6. 数据可视化
  7. 综合练习
  8. 知识点速查表

1. 环境配置与数据导入

1.1 必要模块导入

📌 核心概念

在进行数据分析前,需要导入必要的Python库来支持数据处理、数值计算和可视化功能。

📝 代码示例

python 复制代码
# 导入数值计算库
import numpy as np

# 导入数据分析库
import pandas as pd

# 导入绘图库
import matplotlib.pyplot as plt

# 导入统计可视化库(可选)
import seaborn as sns

# 忽略警告信息(可选)
import warnings
warnings.filterwarnings('ignore')

💡 知识点:各库的作用

  • NumPy: 提供高性能的数值计算和数组操作
  • Pandas: 提供数据结构(DataFrame、Series)和数据分析工具
  • Matplotlib: Python的基础绘图库,用于创建各种静态图表
  • Seaborn: 基于Matplotlib的高级可视化库,提供更美观的统计图表

1.2 中文显示配置

📌 核心概念

Matplotlib默认不支持中文显示,需要配置字体才能正常显示中文标签和标题。

📝 代码示例

python 复制代码
# 设置中文字体为黑体(SimHei)
plt.rcParams['font.sans-serif'] = 'SimHei'

# 正常显示负号(解决负号显示为方块的问题)
plt.rcParams['axes.unicode_minus'] = False

⚠️ 注意事项

  • 必须在绘图前设置字体,否则中文会显示为方块
  • SimHei(黑体)是Windows系统常用的中文字体
  • Mac系统可使用'Arial Unicode MS''PingFang SC'
  • Linux系统可使用'WenQuanYi Micro Hei'

1.3 数据读取

🔧 函数:pd.read_csv()

📊 参数说明

参数 类型 说明 默认值
filepath str 文件路径 必填
encoding str 文件编码格式 'utf-8'
sep str 分隔符 ','
header int/None 表头行号 0
index_col int/str/list 用作索引的列 None

📝 代码示例

python 复制代码
# 读取CSV文件(GBK编码)
data = pd.read_csv('HR.csv', encoding='gbk')

# 读取CSV文件(UTF-8编码)
data = pd.read_csv('data.csv', encoding='utf-8')

# 指定第一列为索引
data = pd.read_csv('data.csv', index_col=0)

⚠️ 常见编码问题

  • GBK: 中文Windows系统常用编码
  • UTF-8: 国际通用编码,推荐使用
  • GB2312: 简体中文编码
  • 如果出现乱码,尝试更换encoding参数

💎 最佳实践

python 复制代码
✅ 推荐:使用相对路径
data = pd.read_csv('./data/HR.csv', encoding='gbk')

❌ 避免:使用绝对路径(降低代码可移植性)
data = pd.read_csv('C:/Users/Desktop/HR.csv', encoding='gbk')

2. 描述性统计分析

📌 核心概念

描述性统计分析是数据分析的第一步,通过统计指标和可视化方法快速了解数据的整体特征、分布情况和潜在问题。

2.1 数据完整性分析

💡 知识点:数据完整性检查

在分析数据前,首先要了解数据的基本信息,包括数据类型、缺失值情况、内存占用等。

🔧 函数:DataFrame.info()

📝 代码示例

python 复制代码
# 查看数据基本信息
data.info()

# 输出示例:
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 15000 entries, 0 to 14999
# Data columns (total 10 columns):
#  #   Column    Non-Null Count  Dtype  
# ---  ------    --------------  -----  
#  0   员工满意度    15000 non-null  float64
#  1   考核评分     15000 non-null  float64
#  2   项目数量     15000 non-null  int64  
# ...

📊 info()输出信息解读

信息项 含义 用途
RangeIndex 索引范围 了解数据行数
Non-Null Count 非空值数量 检测缺失值
Dtype 数据类型 区分数值型/类别型
memory usage 内存占用 评估数据规模

💎 最佳实践

  • 数据分析的第一步必须执行info()
  • 检查Non-Null Count是否等于总行数,判断是否有缺失值
  • 根据Dtype区分数值型和类别型数据,采用不同的分析方法

2.2 数值型数据描述分析

📌 核心概念

数值型数据(连续型数据)通过统计量和分布图来描述其集中趋势、离散程度和分布形态。

🔧 函数:DataFrame.describe()

💡 知识点:8个统计量
describe()默认计算数值型列的8个统计指标,全面描述数据分布特征。

📊 统计量说明

统计量 英文 含义 计算方法
count 计数 非空值数量 统计非NaN值个数
mean 均值 平均值 sum(x) / count(x)
std 标准差 离散程度 衡量数据波动性
min 最小值 最小观测值 数据中的最小数
25% 下四分位数 Q1分位点 25%的数据小于此值
50% 中位数 Q2分位点 50%的数据小于此值
75% 上四分位数 Q3分位点 75%的数据小于此值
max 最大值 最大观测值 数据中的最大数

📝 代码示例

python 复制代码
# 获取数值型数据的描述统计
data.describe()

# 输出示例:
#        员工满意度      考核评分  每月在公司工作时间
# count  15000.0    15000.0    15000.0
# mean      0.61       0.72      201.05
# std       0.25       0.18       49.94
# min       0.09       0.36       96.00
# 25%       0.44       0.56      156.00
# 50%       0.64       0.72      200.00
# 75%       0.82       0.87      245.00
# max       1.00       1.00      310.00

🎯 应用场景

  • 快速了解数据范围: 通过min和max判断是否有异常值
  • 评估数据集中趋势: 通过mean和median(50%)判断数据中心位置
  • 评估数据离散程度: 通过std判断数据波动大小
  • 检测数据偏态: 比较mean和median,判断数据是否偏态分布

2.3 数值型数据可视化

💡 知识点:三种常用图表

数值型数据可通过直方图、箱线图、密度曲线图来展示分布特征。

2.3.1 直方图(Histogram)

📌 核心概念

直方图将数据分成若干区间(bins),统计每个区间的频数,展示数据的分布形态。

📝 代码示例

python 复制代码
# 创建画布
fig = plt.figure(figsize=(16, 4), dpi=100)

# 添加子图
fig.add_subplot(1, 3, 1)

# 绘制直方图
data['员工满意度'].plot(kind='hist')

# 添加标题
plt.title('员工满意度分布情况')

# 显示图像
plt.show()

🎯 应用场景

  • 观察数据的分布形态(正态分布、偏态分布等)
  • 识别数据的集中区间
  • 发现异常值或离群点
2.3.2 箱线图(Box Plot)

📌 核心概念

箱线图通过五数概括(最小值、Q1、中位数、Q3、最大值)展示数据的分布和离群点。

📝 代码示例

python 复制代码
# 绘制箱线图
data['考核评分'].plot(kind='box')
plt.title('考核评分分布情况')
plt.show()

📊 箱线图结构解读

复制代码
    最大值 ─────┐
                │
    Q3 ────┬────┤
           │    │  ← 箱体(IQR:四分位距)
    中位数 ├────┤
           │    │
    Q1 ────┴────┤
                │
    最小值 ─────┘
    
    ○ ← 离群点(超出1.5倍IQR的点)

🎯 应用场景

  • 快速识别离群点
  • 比较多组数据的分布差异
  • 评估数据的对称性
2.3.3 密度曲线图(KDE)

📌 核心概念

核密度估计图(Kernel Density Estimation)是对直方图的平滑化,展示数据的概率密度分布。

📝 代码示例

python 复制代码
# 方法1:使用seaborn
import seaborn as sns
sns.kdeplot(data['每月在公司工作时间'])
plt.title('每月在公司工作时间分布情况')
plt.show()

# 方法2:使用pandas(可能出现警告)
data['每月在公司工作时间'].plot(kind='kde')
plt.title('每月在公司工作时间分布情况')
plt.show()

⚠️ 注意事项

  • Pandas的plot(kind='kde')在某些版本可能产生警告
  • 推荐使用seaborn.kdeplot(),更稳定且功能更强

🔍 对比说明:直方图 vs 密度曲线图

特性 直方图 密度曲线图
展示方式 柱状图 平滑曲线
Y轴含义 频数 概率密度
优点 直观、易理解 平滑、美观
缺点 受bins影响大 可能过度平滑
2.3.4 多子图布局

💡 知识点:创建多子图画布

使用figure()add_subplot()创建包含多个图表的画布。

📝 代码示例

python 复制代码
# 创建画布:宽16英寸,高4英寸,分辨率100dpi
fig1 = plt.figure(figsize=(16, 4), dpi=100)

# 添加第一个子图(1行3列的第1个位置)
fig1.add_subplot(1, 3, 1)
data['员工满意度'].plot(kind='hist')
plt.title('员工满意度分布情况')

# 添加第二个子图(1行3列的第2个位置)
fig1.add_subplot(1, 3, 2)
data['考核评分'].plot(kind='box')
plt.title('考核评分分布情况')

# 添加第三个子图(1行3列的第3个位置)
fig1.add_subplot(1, 3, 3)
sns.kdeplot(data['每月在公司工作时间'])
plt.title('每月在公司工作时间分布情况')

# 显示所有子图
plt.show()

📊 add_subplot()参数说明

参数格式 含义 示例
(nrows, ncols, index) 行数、列数、位置 (2, 3, 1)
简写形式 三位数字 231 等同于 (2,3,1)

💎 最佳实践

python 复制代码
✅ 推荐:使用元组形式,代码更清晰
fig.add_subplot(2, 3, 1)

✅ 推荐:设置合适的figsize和dpi
fig = plt.figure(figsize=(15, 10), dpi=100)

❌ 避免:dpi设置过高导致渲染慢
fig = plt.figure(dpi=300)  # 通常100-150即可

2.4 类别型数据描述分析

📌 核心概念

类别型数据(离散型数据)通过频数统计和分类图表来描述其分布特征。

🔧 函数:select_dtypes() + describe()

💡 知识点:筛选特定类型的列

使用select_dtypes()可以筛选出指定数据类型的列进行分析。

📝 代码示例

python 复制代码
# 筛选类别型数据(object类型)
categorical_data = data.select_dtypes('object')

# 查看类别型数据的描述统计
categorical_data.describe()

# 输出示例:
#        部门    薪水
# count  15000  15000
# unique    10      3
# top    sales    low
# freq    4140   7316

📊 类别型describe()输出解读

统计量 含义 说明
count 非空元素数目 该列有多少个非空值
unique 唯一值数量 去重后有多少个不同类别
top 众数 出现次数最多的类别
freq 众数频数 众数出现的次数

🔧 函数:value_counts()

💡 知识点:统计每个类别的频数
value_counts()返回每个唯一值的出现次数,默认降序排列。

📝 代码示例

python 复制代码
# 统计单个列的类别分布
data['部门'].value_counts()

# 输出示例:
# sales          4140
# technical      2720
# support        2229
# IT             1227
# ...

# 循环查看所有类别型列的详细分布
for col in data.select_dtypes('object'):
    print(f"\n{col}列的分布情况:")
    print(data[col].value_counts())

📊 value_counts()参数说明

参数 类型 说明 默认值
normalize bool 是否返回比例 False
sort bool 是否排序 True
ascending bool 升序/降序 False
dropna bool 是否排除NaN True

💎 最佳实践

python 复制代码
✅ 推荐:查看比例分布
data['薪水'].value_counts(normalize=True)

✅ 推荐:重置索引便于后续操作
data['region'].value_counts().reset_index()

2.5 类别型数据可视化

💡 知识点:三种常用图表

类别型数据可通过柱形图、条形图、饼图来展示分布情况。

2.5.1 柱形图(Bar Chart)

📝 代码示例

python 复制代码
# 绘制垂直柱形图
data['项目数量'].value_counts().plot(kind='bar', rot=0)
plt.title('项目数量分布可视化')
plt.show()

📊 参数说明

参数 含义 常用值
kind 图表类型 'bar'
rot 标签旋转角度 0, 45, 90
color 颜色 颜色名或十六进制
2.5.2 条形图(Horizontal Bar)

📝 代码示例

python 复制代码
# 绘制水平条形图
data['司龄'].value_counts().plot(kind='barh', rot=0)
plt.title('司龄分布可视化')
plt.show()

🔍 对比说明:柱形图 vs 条形图

特性 柱形图(bar) 条形图(barh)
方向 垂直 水平
适用场景 类别少 类别多、标签长
kind参数 'bar' 'barh'
2.5.3 饼图(Pie Chart)

📝 代码示例

python 复制代码
# 绘制饼图
data['工作事故'].value_counts().plot(
    kind='pie',
    autopct='%.2f%%'  # 显示百分比,保留2位小数
)
plt.title('工作事故分布可视化')
plt.show()

📊 饼图参数说明

参数 含义 示例
autopct 百分比格式 '%.2f%%'
startangle 起始角度 90
explode 突出显示 [0.1, 0, 0]
shadow 阴影效果 True

⚠️ 注意事项

  • 饼图适合展示占比关系,类别不宜超过7个
  • autopct='%.2f%%'中的%%表示显示百分号符号
  • 饼图会自动计算百分比,无需手动计算

3. 分组分析

📌 核心概念

分组分析(GroupBy)是将数据按照一个或多个字段分组,然后对每组数据进行聚合计算,是数据分析中最重要的操作之一。

3.1 基础分组操作

🔧 函数:DataFrame.groupby()

💡 知识点:分组的基本语法
groupby()将数据按指定列分组,返回一个GroupBy对象,需要配合聚合函数使用。

📝 代码示例

python 复制代码
# 按单个字段分组,计算均值
result = data.groupby(by='是否离职')['员工满意度'].mean()

# 输出示例:
# 是否离职
# 0    0.666810
# 1    0.440098
# Name: 员工满意度, dtype: float64

📊 groupby()核心参数

参数 类型 说明 默认值
by str/list 分组依据的列名 必填
as_index bool 分组键是否作为索引 True
sort bool 是否对分组键排序 True

💡 知识点:as_index参数的作用

📝 代码示例

python 复制代码
# as_index=True(默认):分组键作为行索引
result1 = data.groupby(by='是否离职')['员工满意度'].mean()
# 输出:
# 是否离职
# 0    0.666810
# 1    0.440098

# as_index=False:分组键作为普通列
result2 = data.groupby(by='是否离职', as_index=False)['员工满意度'].mean()
# 输出:
#    是否离职    员工满意度
# 0      0    0.666810
# 1      1    0.440098

🔍 对比说明

as_index 分组键位置 适用场景
True 行索引 快速查看结果
False 普通列 需要进一步处理数据

💎 最佳实践

python 复制代码
✅ 推荐:需要继续操作时使用as_index=False
result = data.groupby(by='部门', as_index=False)['考核评分'].mean()
result.sort_values(by='考核评分', ascending=False)

❌ 避免:as_index=True时难以排序
result = data.groupby(by='部门')['考核评分'].mean()
result.sort_values(ascending=False)  # 可以,但不够直观

3.2 多字段分组

💡 知识点:按多个字段分组

传入列名列表可实现多层级分组,适用于交叉分析场景。

📝 代码示例

python 复制代码
# 按两个字段分组
result = data.groupby(
    by=['部门', '是否离职'], 
    as_index=False
)['员工满意度'].max()

# 输出示例:
#      部门  是否离职    员工满意度
# 0    IT      0    1.00
# 1    IT      1    1.00
# 2  sales     0    1.00
# 3  sales     1    1.00

🎯 应用场景

  • 交叉分析:同时考虑多个维度
  • 细分市场分析:按地区+产品类别分组
  • 对比分析:按时间+类别分组

3.3 常用聚合函数

💡 知识点:GroupBy对象支持的聚合方法

📊 聚合函数列表

函数 功能 示例
mean() 均值 .mean()
sum() 求和 .sum()
count() 计数 .count()
max() 最大值 .max()
min() 最小值 .min()
std() 标准差 .std()
var() 方差 .var()
median() 中位数 .median()
describe() 描述统计 .describe()

📝 代码示例

python 复制代码
# 1. 按部门分组,计算考核评分均值
data.groupby(by='部门', as_index=False)['考核评分'].mean()

# 2. 按部门分组,计算工作时长的8个统计量
data.groupby(by='部门')['每月在公司工作时间'].describe()

# 3. 按多字段分组,计算最大值
data.groupby(by=['部门', '是否离职'], as_index=False)['员工满意度'].max()

3.4 多字段多聚合:agg()函数

🔧 函数:agg()

📌 核心概念
agg()(aggregate的缩写)是专门用于分组后聚合的函数,支持对不同字段应用不同的聚合函数。

💡 知识点:agg()的三种用法

用法1:单字段单聚合

📝 代码示例

python 复制代码
# 对单个字段应用单个聚合函数
data.groupby(by='项目数量').agg({'员工满意度': 'mean'})
用法2:单字段多聚合

📝 代码示例

python 复制代码
# 对单个字段应用多个聚合函数
data.groupby(by='部门', as_index=False).agg({
    '员工满意度': ['max', 'min'],
    '每月在公司工作时间': ['mean']
})
用法3:多字段多聚合(最常用)

📝 代码示例

python 复制代码
# 对不同字段应用不同的聚合函数
data1 = data.groupby(by='项目数量').agg({
    '员工满意度': ['mean'],      # 计算均值
    '考核评分': ['max']           # 计算最大值
})

# 输出示例:
#      员工满意度        考核评分
#          mean         max
# 项目数量                    
# 2      0.478760    1.00
# 3      0.571429    1.00
# 4      0.633929    1.00

⚠️ 注意事项:多层索引问题

当使用agg()返回多个聚合结果时,列名会变成多层索引(MultiIndex)。

📝 代码示例

python 复制代码
# 查看列名结构
data1.columns
# 输出:MultiIndex([('员工满意度', 'mean'),
#                  ( '考核评分',  'max')])

# 方法1:使用元组访问列
data1.sort_values(by=[('员工满意度', 'mean')], ascending=False)

# 方法2:重命名列(扁平化)
data1.columns = ['员工满意度均值', '考核评分最大值']
data1.sort_values(by='员工满意度均值', ascending=False)

💎 最佳实践

python 复制代码
✅ 推荐:使用字典明确指定聚合函数
data.groupby('部门').agg({
    '员工满意度': ['mean', 'std'],
    '考核评分': ['max', 'min']
})

✅ 推荐:多层索引时使用元组访问
result.sort_values(by=[('员工满意度', 'mean')], ascending=False)

❌ 避免:混用字符串和列表
data.groupby('部门').agg({'员工满意度': 'mean', '考核评分': ['max']})

3.5 综合练习

📝 练习1:单字段多聚合

python 复制代码
# 按照部门分组,计算员工满意度的最大值和最小值,工作时长的均值
data.groupby(by='部门', as_index=False).agg({
    '员工满意度': ['max', 'min'],
    '每月在公司工作时间': ['mean']
})

📝 练习2:多字段聚合

python 复制代码
# 按照司龄分组,计算工作时长均值和项目数量的标准差
data.groupby(by='司龄').agg({
    '每月在公司工作时间': ['mean'],
    '项目数量': ['std']
})

📝 练习3:多层分组多聚合

python 复制代码
# 按照部门和薪水分组,计算员工满意度的均值和标准差
data.groupby(by=['部门', '薪水']).agg({
    '员工满意度': ['mean', 'std']
})

4. 数据透视表

📌 核心概念

数据透视表(Pivot Table)是一种强大的数据汇总工具,本质是分组聚合的可视化展现,可以快速生成交叉分析表。

🔧 函数:pd.pivot_table()

4.1 基本语法

📊 参数说明

参数 类型 说明 默认值
data DataFrame 数据源 必填
index str/list 行分组键 必填
columns str/list 列分组键 None
values str/list 要聚合的数据列 必填
aggfunc str/dict/list 聚合函数 'mean'
margins bool 是否添加汇总行/列 False
fill_value scalar 填充缺失值 None

💡 知识点:透视表的结构

复制代码
                列分组键(columns)
                项目数量2  项目数量3  项目数量4
行分组键(index)
部门IT           0.618     0.650     0.720
部门sales        0.479     0.571     0.634

4.2 基础透视表

📝 代码示例

python 复制代码
# 按照部门和项目数量分组,得到员工满意度均值
result = pd.pivot_table(
    index='部门',              # 行分组键
    columns='项目数量',         # 列分组键
    values=['员工满意度'],      # 要统计的数据
    aggfunc=['mean'],          # 聚合函数(默认就是mean)
    data=data,                 # 数据源
    margins=True               # 添加汇总行列
)

# 输出示例:
#              员工满意度                    
#                mean                      
# 项目数量           2      3      4    All
# 部门                                    
# IT          0.618  0.650  0.720  0.650
# sales       0.479  0.571  0.634  0.550
# All         0.500  0.600  0.680  0.600

⚠️ 注意事项

  • margins=True会在最后添加"All"行和列,显示总体统计
  • 列分组键的值会成为列名
  • 如果某个组合没有数据,会显示NaN

4.3 多值多聚合透视表

📝 代码示例

python 复制代码
# 按照是否离职和司龄分组,计算工作时间均值和考核评分标准差
df2 = pd.pivot_table(
    data=data,
    index='司龄',                    # 行:司龄
    columns='是否离职',              # 列:是否离职
    values=['每月在公司工作时间', '考核评分'],  # 多个统计字段
    aggfunc={
        '每月在公司工作时间': ['mean'],  # 工作时间计算均值
        '考核评分': 'std'                # 考核评分计算标准差
    }
)

# 保存结果到CSV
df2.to_csv('df2.csv')

🔍 对比说明:groupby vs pivot_table

特性 groupby pivot_table
结果形式 长格式 宽格式(交叉表)
可读性 一般 更直观
灵活性 更灵活 固定格式
适用场景 复杂聚合 交叉分析

💎 最佳实践

python 复制代码
✅ 推荐:需要交叉分析时使用pivot_table
pd.pivot_table(index='部门', columns='薪水', values='员工满意度', aggfunc='mean', data=data)

✅ 推荐:需要多种聚合时使用groupby
data.groupby('部门').agg({'员工满意度': ['mean', 'std', 'max', 'min']})

4.4 计算离职率实战

💡 知识点:使用透视表计算比率

📝 代码示例

python 复制代码
# 计算不同项目数量的离职率
df3 = pd.pivot_table(
    index='项目数量',
    columns='是否离职',
    values='部门',        # 使用任意列进行计数
    aggfunc='count',      # 计数聚合
    data=data
)

# 计算离职率 = 离职人数 / 总人数
df3['离职率'] = df3[1] / (df3[0] + df3[1])

# 按离职率降序排列
df3.sort_values(by='离职率', ascending=False)

# 输出示例:
# 是否离职      0     1      离职率
# 项目数量                        
# 7         256   916   0.781
# 6         215   127   0.371
# 2        2388  3875   0.619

🎯 应用场景

  • 计算转化率、流失率等业务指标
  • 对比不同分组的比率差异
  • 识别高风险群体

5. 交叉表

📌 核心概念

交叉表(Cross Tabulation)是数据透视表的特殊形式,专门用于统计分类变量的频数分布,默认聚合函数是计数。

🔧 函数:pd.crosstab()

5.1 基本用法

📝 代码示例

python 复制代码
# 计算不同部门的离职率
df4 = pd.crosstab(
    index=data['部门'],      # 行分组
    columns=data['是否离职']  # 列分组
)

# 输出示例:
# 是否离职      0     1
# 部门                  
# IT          767   460
# sales      2720  1420
# support    1473   756

# 计算离职率
df4['离职率'] = df4[1] / (df4[0] + df4[1])

📊 crosstab()参数说明

参数 类型 说明 默认值
index Series/array 行分组数据 必填
columns Series/array 列分组数据 必填
values Series/array 聚合的值 None
aggfunc function 聚合函数 count
margins bool 添加汇总 False
normalize bool/str 归一化 False

5.2 交叉表 vs 透视表

🔍 对比说明

特性 crosstab pivot_table
默认聚合 计数(count) 均值(mean)
参数数量 较少 较多
灵活性 专注计数 支持各种聚合
使用场景 频数统计 通用聚合分析

💡 知识点:何时使用哪个?

python 复制代码
✅ 使用crosstab:纯粹的分类计数
pd.crosstab(index=df['region'], columns=df['category'])

✅ 使用pivot_table:需要其他聚合函数
pd.pivot_table(index='region', columns='category', values='sales', aggfunc='sum', data=df)

⚠️ 重要说明

  • 交叉表能完成的,透视表都能完成(设置aggfunc='count'
  • 但交叉表语法更简洁,专门用于计数场景
  • 透视表功能更强大,支持复杂的聚合需求

📝 等价代码示例

python 复制代码
# 方法1:使用crosstab
result1 = pd.crosstab(index=df['region'], columns=df['category'])

# 方法2:使用pivot_table(等价)
result2 = pd.pivot_table(
    index='region',
    columns='category',
    values='order_id',  # 任意列
    aggfunc='count',
    data=df
)

5.3 unstack()方法

💡 知识点:将多层索引转换为透视表格式

📝 代码示例

python 复制代码
# 使用groupby + unstack实现交叉表效果
result = data.groupby(by=['region', 'category'])['order_id'].count().unstack()

# 等价于
result = pd.crosstab(index=df['region'], columns=df['category'])

🔍 对比说明:三种方法

方法 代码复杂度 灵活性 推荐度
crosstab ⭐ 简单 ⭐⭐ 中等 ⭐⭐⭐
pivot_table ⭐⭐ 中等 ⭐⭐⭐ 高 ⭐⭐⭐
groupby+unstack ⭐⭐⭐ 复杂 ⭐⭐⭐ 高 ⭐⭐

6. 数据可视化

6.1 DataFrame绘图方法

🔧 函数:DataFrame.plot()

📌 核心概念

Pandas的DataFrame和Series对象内置了plot()方法,可以快速创建各种图表。

📊 plot()参数说明

参数 类型 说明 常用值
kind str 图表类型 'line', 'bar', 'barh', 'hist', 'box', 'kde', 'scatter', 'pie'
x str X轴数据列 列名
y str Y轴数据列 列名
figsize tuple 图表尺寸 (8, 6)
title str 图表标题 字符串
rot int 标签旋转角度 0, 45, 90
color str/list 颜色 颜色名或列表

6.2 常用图表类型

6.2.1 柱状图

📝 代码示例

python 复制代码
# 分组后绘制柱状图
df.groupby(by='category')['sales'].sum().plot(kind='bar', rot=0)
plt.title('各产品类别的销售总额柱状图')
plt.show()
6.2.2 折线图

📝 代码示例

python 复制代码
# 绘制时间序列折线图
df.plot(x='date', y='sales', kind='line')
plt.title('销售额随时间变化的折线图')
plt.ylabel('销售额')
plt.show()
6.2.3 散点图

📝 代码示例

python 复制代码
# 绘制两个变量的散点图
df.plot(x='quantity', y='sales', kind='scatter')
plt.title('销售额与数量的散点图')
plt.show()

6.3 自定义绘图

💡 知识点:使用Matplotlib进行精细控制

📝 代码示例

python 复制代码
# 创建画布
plt.figure(figsize=(8, 6))

# 准备数据
x = df.groupby('category')['sales'].sum().index
y = df.groupby('category')['sales'].sum().values

# 绘制柱状图
plt.bar(x, y, color=['#1f77b4', '#ff7f0e', '#2ca02c'])

# 设置标题和标签
plt.title('各商品类别销售总额', fontsize=14, pad=20)
plt.xlabel('商品类别', fontsize=12)
plt.ylabel('总销售额(元)', fontsize=12)

# 添加网格线
plt.grid(axis='y', alpha=0.3)

# 自动调整布局
plt.tight_layout()

# 显示图表
plt.show()

📊 常用参数说明

参数 说明 示例
figsize 图表尺寸(宽,高) (8, 6)
fontsize 字体大小 14
pad 标题与图表间距 20
alpha 透明度 0.3
color 颜色列表 ['#1f77b4', '#ff7f0e']

💎 最佳实践

python 复制代码
✅ 推荐:使用tight_layout()自动调整布局
plt.tight_layout()

✅ 推荐:设置合适的figsize和fontsize
plt.figure(figsize=(10, 6))
plt.title('标题', fontsize=14)

✅ 推荐:添加网格线提高可读性
plt.grid(axis='y', alpha=0.3)

7. 综合练习

7.1 数据排序

🔧 函数:DataFrame.sort_values()

📝 代码示例

python 复制代码
# 找出销售额最高的5笔订单
df.sort_values(by='sales', ascending=False).head()

# 输出示例:
#     order_id product  category region  sales  quantity
# 15      1016      电视    电子产品     华东   4998         9
# 3       1004      手机    电子产品     华南   4800         7

📊 参数说明

参数 说明 默认值
by 排序依据的列 必填
ascending 升序/降序 True
inplace 是否原地修改 False
na_position NaN值位置 'last'

7.2 索引重置

🔧 函数:reset_index()

💡 知识点:将索引转换为普通列

📝 代码示例

python 复制代码
# value_counts()结果的索引是类别值
counts = df['region'].value_counts()
# 输出:
# 华东    8
# 华南    7
# 华北    5

# 重置索引,将类别值变为普通列
counts_df = df['region'].value_counts().reset_index()
# 输出:
#   region  count
# 0   华东      8
# 1   华南      7
# 2   华北      5

🎯 应用场景

  • 将聚合结果转换为DataFrame便于后续操作
  • 将多层索引展平
  • 为结果添加序号列

7.3 新增计算列

💡 知识点:基于现有列创建新列

📝 代码示例

python 复制代码
# 新建单价列:销售额除以数量
df['unit_price'] = df['sales'] / df['quantity']

# 四舍五入保留2位小数
df['unit_price'] = np.round(df['unit_price'], 2)

# 查看结果
df[['sales', 'quantity', 'unit_price']].head()

🔧 函数:np.round()

📊 参数说明

参数 说明 示例
a 要四舍五入的数组 df['unit_price']
decimals 保留小数位数 2

💎 最佳实践

python 复制代码
✅ 推荐:使用向量化操作
df['unit_price'] = df['sales'] / df['quantity']

❌ 避免:使用循环(效率低)
for i in range(len(df)):
    df.loc[i, 'unit_price'] = df.loc[i, 'sales'] / df.loc[i, 'quantity']

7.4 综合练习题解答

📝 练习1:找出销售额最高的5笔订单

python 复制代码
df.sort_values(by='sales', ascending=False).head()

📝 练习2:统计每个区域的订单数量

python 复制代码
df['region'].value_counts().reset_index()

📝 练习3:得到各商品类别的总销售额

python 复制代码
df.groupby(by='category', as_index=False)['sales'].sum()

📝 练习4:得到各区域的总销售额

python 复制代码
df.groupby(by='region', as_index=False)['sales'].sum()

📝 练习5:使用pivot_table统计各地区-各商品类别的平均销售额

python 复制代码
pd.pivot_table(
    data=df,
    index='region',
    columns='category',
    values='sales',
    aggfunc=['mean']
)

📝 练习6:绘制各产品类别的销售总额柱状图

python 复制代码
df.groupby(by='category')['sales'].sum().plot(kind='bar', rot=0)
plt.title('各产品类别的销售总额柱状图')
plt.show()

📝 练习7:绘制销售额随时间变化的折线图

python 复制代码
df.plot(x='date', y='sales', kind='line')
plt.title('销售额随时间变化的折线图')
plt.ylabel('销售额')
plt.show()

📝 练习8:绘制销售额与数量的散点图

python 复制代码
df.plot(x='quantity', y='sales', kind='scatter')
plt.title('销售额与数量的散点图')
plt.show()

📝 练习9:新建单价列

python 复制代码
df['unit_price'] = df['sales'] / df['quantity']
df['unit_price'] = np.round(df['unit_price'], 2)

📝 练习10:各区域不同商品类别订单数量

python 复制代码
# 方法1:使用crosstab
pd.crosstab(index=df['region'], columns=df['category'])

# 方法2:使用groupby + unstack
df.groupby(by=['region', 'category'])['order_id'].count().unstack()

8. 知识点速查表

📊 核心函数速查

⭐ 基础必学
函数 功能 语法示例
info() 数据概览 data.info()
describe() 描述统计 data.describe()
value_counts() 频数统计 data['列名'].value_counts()
groupby() 分组 data.groupby('列名')
plot() 绘图 data.plot(kind='bar')
⭐⭐ 进阶提升
函数 功能 语法示例
agg() 多聚合 data.groupby('列').agg({'列1': 'mean', '列2': 'sum'})
pivot_table() 数据透视表 pd.pivot_table(index='行', columns='列', values='值', data=data)
crosstab() 交叉表 pd.crosstab(index=data['列1'], columns=data['列2'])
select_dtypes() 筛选类型 data.select_dtypes('object')
reset_index() 重置索引 result.reset_index()
⭐⭐⭐ 高级技巧
函数 功能 语法示例
unstack() 索引转列 data.groupby(['列1', '列2']).count().unstack()
sort_values() 排序 data.sort_values(by='列', ascending=False)
add_subplot() 添加子图 fig.add_subplot(2, 3, 1)
sns.kdeplot() 密度曲线 sns.kdeplot(data['列'])

📈 图表类型速查

图表类型 kind参数 适用数据 主要用途
直方图 'hist' 数值型 查看分布形态
箱线图 'box' 数值型 识别离群点
密度图 'kde' 数值型 平滑分布曲线
柱形图 'bar' 类别型 比较类别频数
条形图 'barh' 类别型 类别多时使用
饼图 'pie' 类别型 展示占比关系
折线图 'line' 时间序列 展示趋势变化
散点图 'scatter' 两个数值 查看相关性

🎯 分析流程速查

复制代码
数据导入
    ↓
data.info() ──→ 检查数据完整性
    ↓
数据类型判断
    ↓
┌───────────────┬───────────────┐
│   数值型数据   │   类别型数据   │
│               │               │
│ describe()    │ value_counts()│
│ hist/box/kde  │ bar/barh/pie  │
└───────────────┴───────────────┘
    ↓
分组分析
    ↓
┌───────────────┬───────────────┐
│   groupby()   │ pivot_table() │
│   + agg()     │  / crosstab() │
└───────────────┴───────────────┘
    ↓
结果可视化

💡 常见问题速查

Q1: 中文显示乱码?
python 复制代码
✅ 解决方案:
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
Q2: 如何选择分组函数?
python 复制代码
✅ 简单计数 → crosstab()
✅ 交叉分析 → pivot_table()
✅ 复杂聚合 → groupby() + agg()
Q3: 多层索引如何访问?
python 复制代码
✅ 使用元组:
result.sort_values(by=[('列名', '聚合函数')], ascending=False)

✅ 或重命名:
result.columns = ['新列名1', '新列名2']
Q4: 如何计算比率?
python 复制代码
✅ 先用pivot_table或crosstab统计频数
df = pd.crosstab(index=data['列1'], columns=data['列2'])

✅ 再计算比率
df['比率'] = df[1] / (df[0] + df[1])

🔗 关联知识点

复制代码
描述性统计分析
    ├─ 数据完整性 → info()
    ├─ 数值型分析 → describe(), hist, box, kde
    └─ 类别型分析 → value_counts(), bar, pie

分组分析
    ├─ 单层分组 → groupby(by='列')
    ├─ 多层分组 → groupby(by=['列1', '列2'])
    └─ 多聚合 → agg({'列1': 'mean', '列2': ['max', 'min']})

数据透视
    ├─ 通用透视 → pivot_table()
    ├─ 频数统计 → crosstab()
    └─ 索引转换 → unstack()

数据可视化
    ├─ 快速绘图 → DataFrame.plot()
    ├─ 精细控制 → matplotlib
    └─ 统计图表 → seaborn

💎 最佳实践总结

1. 数据分析流程

python 复制代码
# 第一步:导入数据
data = pd.read_csv('data.csv', encoding='gbk')

# 第二步:数据概览
data.info()
data.head()

# 第三步:描述统计
data.describe()  # 数值型
data.select_dtypes('object').describe()  # 类别型

# 第四步:分组分析
data.groupby('分组列').agg({'统计列': '聚合函数'})

# 第五步:可视化
data.plot(kind='图表类型')

2. 代码规范

python 复制代码
✅ 推荐:使用as_index=False便于后续操作
data.groupby(by='列', as_index=False)['值'].mean()

✅ 推荐:为图表添加标题和标签
plt.title('标题')
plt.xlabel('X轴')
plt.ylabel('Y轴')

✅ 推荐:使用字典明确指定聚合函数
data.groupby('列').agg({'列1': 'mean', '列2': ['max', 'min']})

3. 性能优化

python 复制代码
🚀 使用向量化操作代替循环
df['新列'] = df['列1'] / df['列2']  

🚀 使用内置函数代替自定义函数
data.groupby('列')['值'].mean()  

4. 常见错误避免

python 复制代码
❌ 忘记设置中文字体
plt.rcParams['font.sans-serif'] = 'SimHei'

❌ 多层索引访问错误
result.sort_values(by='列名')  # 错误
result.sort_values(by=[('列名', '聚合函数')])  # 正确

❌ 混淆crosstab和pivot_table的参数
pd.crosstab(index='列1', columns='列2')  # 错误
pd.crosstab(index=data['列1'], columns=data['列2'])  # 正确

🎓 学习建议

1. 理解核心概念

  • 描述性统计的目的是快速了解数据
  • 分组分析的本质是分而治之
  • 透视表是分组聚合的可视化展现

2. 多练习实战

  • 使用真实数据集练习(如HR数据、销售数据)
  • 尝试不同的分组组合和聚合函数
  • 对比不同可视化方法的效果

3. 掌握工具选择

  • 简单计数value_counts()crosstab()
  • 交叉分析pivot_table()
  • 复杂聚合groupby() + agg()
  • 快速可视化DataFrame.plot()
  • 精美图表matplotlib + seaborn

4. 注意细节

  • 始终检查数据类型(数值型 vs 类别型)
  • 注意缺失值的处理
  • 合理选择聚合函数(均值、中位数、求和等)
  • 为图表添加清晰的标题和标签

💡 核心要点 :Pandas的描述分析和分组分析是数据分析的基础,掌握这些技能可以快速从数据中提取有价值的信息。记住:先了解数据(describe),再分组分析(groupby),最后可视化展示(plot)

相关推荐
雷工笔记1 小时前
MES学习笔记之SCADA采集的数据如何与MES中的任务关联起来?
笔记·学习
繁星星繁2 小时前
【C++】脚手架学习笔记 gflags与 gtest
c++·笔记·学习
Lovely Ruby3 小时前
前端er Go-Frame 的学习笔记:实现 to-do 功能(三),用 docker 封装成镜像,并且同时启动前后端数据库服务
前端·学习·golang
YJlio3 小时前
SDelete 学习笔记(9.18):安全删除、空闲清理与介质回收实战
笔记·学习·安全
来鸟 鸣间4 小时前
日常简单数据分析之matlab (一)
matlab·数据分析
d111111111d5 小时前
STM32低功耗学习-停止模式-(学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习
找了一圈尾巴5 小时前
LLM-as-a-Judge-论文学习(下)
学习·模型评估
@游子5 小时前
Python学习笔记-Day5
笔记·python·学习
漏洞文库-Web安全6 小时前
Linux逆向学习记录
linux·运维·学习·安全·web安全·网络安全·逆向