查看全课大纲(第 48 / 101 节)
  1. 1.数据分析基本概念
  2. 2.学习数据分析的一般路线
  3. 3.数据分析的流程
  4. 4.数据类型
  5. 5.环境部署(1)
  6. 6.环境部署(2)
  7. 7.课程介绍
  8. 8.TXT文件操作
  9. 9.JSON文件操作
  10. 10.CSV文件操作
  11. 11.Excel文件操作
  12. 12.数据库及SQL常用语法
  13. 13.数据库基本操作
  14. 14.数据库多表连接
  15. 15.实战:欧洲职业足球数据库分析
  16. 16.爬虫简介
  17. 17.URL管理模块
  18. 18.网页下载模块
  19. 19.网页解析模块(1)
  20. 20.网页解析模块(2)
  21. 21.Scrapy简介
  22. 22.Scrapy使用步骤(1)
  23. 23.Scrapy使用步骤(2)
  24. 24.Scrapy使用步骤(3)
  25. 25.Scrapy使用步骤(4)
  26. 26.实战:获取国内城市空气质量指数数据
  27. 27.NumPy和SciPy介绍
  28. 28.多维数组
  29. 29.多维数组操作
  30. 30.NumPy的常用方法
  31. 31.向量化介绍
  32. 32.向量化及通用函数
  33. 33.实战:2016美国大选分析
  34. 34.数据结构-Series
  35. 35.数据结构-DataFrame
  36. 36.数据结构-Index
  37. 37.Series的索引操作
  38. 38.DataFrame的索引操作
  39. 39.索引操作总结
  40. 40.运算与对齐
  41. 41.函数应用操作(1) -- map
  42. 42.函数应用操作 (2) -- apply applymap
  43. 43.文件读写操作
  44. 44.排序操作
  45. 45.数据清洗--处理缺失数据
  46. 46.数据清洗--处理重复数据
  47. 47.数据清洗--替换数据
  48. 48.常用统计方法(1) -- describe quantile
  49. 49.常用统计方法(2) -- sum mean median count
  50. 50.常用统计方法(3) -- max min idxmax idxmin
  51. 51.常用统计方法(4) -- mad var std cumsum
  52. 52.实战:全球食品数据分析
  53. 53.层级索引
  54. 54.分组与聚合介绍
  55. 55.分组操作(1) -- GroupBy对象及常用聚合操作
  56. 56.分组操作(2) -- 自定义分组及聚合操作
  57. 57.透视表介绍
  58. 58.透视表操作
  59. 59.数据规整(1) -- 数据合并concat
  60. 60.数据规整(2) -- 数据连接merge
  61. 61.数据重构(3) -- 数据重构stack unstack
  62. 62.实战:互联网电影资料库分析
  63. 63.探索性数据分析EDA介绍
  64. 64.EDA的目的
  65. 65.EDA常用工具
  66. 66.Matplotlib绘图基本介绍
  67. 67.Matplotlib画布
  68. 68.散点图和柱状图的绘制
  69. 69.直方图的绘制
  70. 70.矩阵绘图
  71. 71.子图的使用
  72. 72.Matplotlib颜色、标记、线型
  73. 73.Matplotlib坐标刻度、标签、图例、标题
  74. 74.Seaborn介绍
  75. 75.数据集分布可视化(1) -- 单变量分布、双变量分布
  76. 76.数据集分布可视化(2) -- 变量关系可视化
  77. 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
  78. 78.交互式数据可视化工具Bokeh介绍
  79. 79.Bokeh绘制散点图、柱状图、盒子图、弦图
  80. 80.Bokeh绘制常用图形元素
  81. 81.3D绘图 -- mplot3d
  82. 82.3D曲线可视化
  83. 83.3D散点图可视化
  84. 84.3D柱状图可视化
  85. 85.Pandas绘图
  86. 86.实战:Lending Club借贷数据探索性分析及可视化
  87. 87.机器学习介绍及应用场景
  88. 88.机器学习建模介绍 (1) -- 分类
  89. 89.机器学习建模介绍 (2) -- 回归
  90. 90.机器学习建模介绍 (3) -- 聚类
  91. 91.机器学习分类
  92. 92.机器学习工具scikit-learn
  93. 93.使用scikit-learn的流程
  94. 94.数据集准备及划分
  95. 95.模型选择
  96. 96.数据预处理及特征工程
  97. 97.过拟合与欠拟合
  98. 98.模型调参介绍
  99. 99.模型调参方法
  100. 100.模型测试及评价
  101. 101.实战:通过移动设备行为数据预测性别和年龄

常用统计方法(1) -- describe quantile

约 9 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

常用统计方法(1) – describe、quantile

小象实战讲义 · Python数据分析实战

在数据分析中,我们经常需要对数据的整体分布有一个快速、全面的了解。Pandas提供了两个非常强大的工具——describe()和quantile()方法,它们能帮助我们高效地计算数据的核心统计量,洞察数据的集中趋势、离散程度和分布形态。本节将深入讲解这两个方法的使用及其背后的统计含义。

💡 核心导读

  • describe():一键生成描述性统计摘要,包括计数、均值、标准差、最小值、四分位数和最大值。
  • 四分位数:理解25%、50%、75%分位数的计算方法和统计意义,特别是中位数与均值的区别。
  • quantile():灵活计算任意指定位置的百分位数,例如中位数(q=0.5)或第一四分位数(q=0.25)。
  • 应用场景:快速数据概览、识别缺失值、发现极端值以及从不同层面理解数据分布。

一、 描述性统计:describe()方法

describe()是Pandas DataFrame和Series对象的一个方法。调用它会返回一个包含多个核心统计量的新DataFrame。这些统计量是针对每一列数值型数据分别计算的。

import pandas as pd

# 构造一个模拟的“幸福指数”数据集小样例
data = {
    'country': ['Country_A', 'Country_B', 'Country_C', 'Country_D', 'Country_E'],
    'happiness_rank': [1, 2, 3, 4, 5],
    'happiness_score': [7.5, 7.4, 7.3, 7.2, 7.1],
    'gdp_per_capita': [1.4, 1.3, 1.2, 1.1, 1.0]
}
df = pd.DataFrame(data)
print("模拟数据集:")
print(df)
print("\n" + "="*50 + "\n")
模拟数据集:
     country  happiness_rank  happiness_score  gdp_per_capita
0  Country_A               1              7.5             1.4
1  Country_B               2              7.4             1.3
2  Country_C               3              7.3             1.2
3  Country_D               4              7.2             1.1
4  Country_E               5              7.1             1.0

==================================================

现在,我们使用describe()方法来查看数值列的统计摘要。

# 使用 describe() 方法获取描述性统计摘要
import pandas as pd

# 重新在块内构造数据,确保自包含
data = {
    'country': ['Country_A', 'Country_B', 'Country_C', 'Country_D', 'Country_E'],
    'happiness_rank': [1, 2, 3, 4, 5],
    'happiness_score': [7.5, 7.4, 7.3, 7.2, 7.1],
    'gdp_per_capita': [1.4, 1.3, 1.2, 1.1, 1.0]
}
df = pd.DataFrame(data)

stat_summary = df.describe()
print("描述性统计摘要:")
print(stat_summary)
描述性统计摘要:
       happiness_rank  happiness_score  gdp_per_capita
count        5.000000         5.000000        5.000000
mean         3.000000         7.300000        1.200000
std          1.581139         0.158114        0.158114
min          1.000000         7.100000        1.000000
25%          2.000000         7.200000        1.100000
50%          3.000000         7.300000        1.200000
75%          4.000000         7.400000        1.300000
max          5.000000         7.500000        1.400000

输出结果解读:

  • count:该列非空(非NaN)数据的个数。这是检查数据完整性的第一道关卡。如果某列的count小于总行数,说明该列存在缺失值。
  • mean:算术平均值,即所有值之和除以个数。
  • std:标准差,衡量数据点相对于均值的离散程度。标准差越大,数据越分散。
  • min:该列的最小值。
  • 25%:第一四分位数(Q1),即第25百分位数。
  • 50%:第二四分位数(Q2),即第50百分位数,也就是中位数。
  • 75%:第三四分位数(Q3),即第75百分位数。
  • max:该列的最大值。

注意:describe()默认只对数值型列进行统计。对于字符串类型的列(如本例中的country),它会被自动排除在统计摘要之外。

二、 深入理解四分位数与中位数

describe()输出的25%、50%、75%这三个分位数非常关键,它们共同描述了数据的分布情况。要理解它们,首先要明白四分位数是基于排序后的数据进行计算的。

1. 计算过程

假设我们有一列已排序的数据:[1, 3, 3, 4, 5, 6, 7, 8, 8]。

  1. 排序:数据本身已排序。
  2. 寻找分界点:
    • Q1 (25%):将数据分为前25%的部分。其位置索引计算方式有多种(如(n+1)*0.25),在Pandas中采用线性插值法。对于本例,大致位于前1/4位置的值是3。
    • Q2 (50%) 中位数:将数据分为两等份。如果数据点个数n为奇数,中位数是正中间的数;如果n为偶数,则是中间两个数的平均值。本例n=9(奇数),中位数是第5个数5。
    • Q3 (75%):将数据分为前75%的部分。大致位于后1/4位置的值是7。

2. 中位数 vs. 均值

这是两个常被混淆但意义不同的中心趋势度量。

  • 均值:所有数据值的算术平均。计算公式为:(x1 + x2 + ... + xn) / n。均值对极端值(极大或极小)非常敏感。
  • 中位数:将数据排序后,位于最中间位置的值。中位数对极端值不敏感,更能反映“典型”情况。

举例:一个地区的房屋价格。如果大部分房屋价格在100-300万,但有几套豪宅价格过亿,那么平均房价会被这几套豪宅显著拉高,无法代表大多数人的购房成本。而房价中位数则能更好地反映普通房屋的价格水平。

describe()同时提供了均值(mean)和中位数(50%),让我们可以对比观察,判断数据分布是否对称,是否存在偏斜或极端值。

三、 灵活计算百分位数:quantile()方法

describe()给出了固定的几个分位数。如果你想计算其他位置的百分位数,就需要使用quantile()方法。quantile(q)中的参数q表示你想要计算的百分位,范围在0到1之间。

  • q=0.5:计算中位数(第50百分位数)。
  • q=0.25:计算第一四分位数(第25百分位数)。
  • q=0.75:计算第三四分位数(第75百分位数)。
  • q也可以是一个列表,用于一次性计算多个百分位数,如q=[0.1, 0.5, 0.9]。
import pandas as pd
import numpy as np

# 构造一个稍大的模拟数据集,用于演示分位数
np.random.seed(42) # 固定随机种子,确保输出确定
sim_data = {
    'score_A': np.random.randn(10) * 10 + 50, # 均值为50,标准差为10的正态分布数据
    'score_B': np.random.randn(10) * 5 + 30,   # 均值为30,标准差为5的正态分布数据
}
df_sim = pd.DataFrame(sim_data)
print("模拟数据集 df_sim:")
print(df_sim)
print("\n" + "="*50 + "\n")

# 1. 计算中位数 (默认 q=0.5)
median_values = df_sim.quantile(q=0.5)
print("各列的中位数 (q=0.5):")
print(median_values)
print("\n" + "="*50 + "\n")

# 2. 计算第一四分位数 (q=0.25)
q1_values = df_sim.quantile(q=0.25)
print("各列的第一四分位数 (q=0.25):")
print(q1_values)
print("\n" + "="*50 + "\n")

# 3. 一次性计算25%, 50%, 75%分位数
import pandas as pd
import numpy as np

np.random.seed(42)
sim_data = {
    'score_A': np.random.randn(10) * 10 + 50,
    'score_B': np.random.randn(10) * 5 + 30,
}
df_sim = pd.DataFrame(sim_data)

multiple_quantiles = df_sim.quantile(q=[0.25, 0.5, 0.75])
print("多个分位数:")
print(multiple_quantiles)
模拟数据集 df_sim:
     score_A    score_B
0  54.967142  27.682912
1  48.617357  27.671351
2  56.476885  31.209811
3  65.230299  20.433599
4  47.658466  21.375411
5  47.658630  27.188562
6  65.792128  24.935844
7  57.674347  31.571237
8  45.305256  25.459880
9  55.425600  22.938481

==================================================

各列的中位数 (q=0.5):
score_A    55.196371
score_B    26.324221
Name: 0.5, dtype: float64

==================================================

各列的第一四分位数 (q=0.25):
score_A    47.898312
score_B    23.437822
Name: 0.25, dtype: float64

==================================================

多个分位数:
        score_A    score_B
0.25  47.898312  23.437822
0.50  55.196371  26.324221
0.75  57.374982  27.680021

可以看到,quantile(q=0.5)的结果与describe()输出的50%行是一致的,quantile(q=0.25)与25%行一致。quantile()为我们提供了按需计算任意百分位数的灵活性。

四、 综合实战演练

原课程使用了2016年全球幸福指数报告数据集。为了便于演示和复现,我们使用模拟数据来演练describe()和quantile()的联合应用。

任务:对模拟的“国家发展指标”数据进行快速探索,完成以下分析:

  1. 使用describe()获得整体数据概览。
  2. 使用quantile()重点关注“幸福分数”的分布情况。
import pandas as pd
import numpy as np

# 模拟一个包含多个指标的国家数据集
np.random.seed(123) # 固定种子,确保结果可复现
n_countries = 20

sim_data = {
    'country': [f'Country_{i:02d}' for i in range(n_countries)],
    'happiness_score': np.round(np.random.uniform(3, 8, n_countries), 2), # 3-8分的幸福分数
    'gdp_per_capita': np.round(np.random.lognormal(1.0, 0.3, n_countries), 3), # 人均GDP
    'life_expectancy': np.round(np.random.normal(75, 5, n_countries), 1), # 预期寿命
    'region': np.random.choice(['North', 'South', 'East', 'West'], n_countries) # 地区
}
sim_df = pd.DataFrame(sim_data)

print("模拟国家发展指标数据集 (前5行):")
print(sim_df.head())
print("\n" + "="*60 + "\n")

# 1. 使用describe()进行整体概览
print("=== 数据集描述性统计摘要 ===")
desc_stats = sim_df.describe()
print(desc_stats)
print("\n" + "="*60 + "\n")

# 2. 使用quantile()关注特定分位数
print("=== 关键百分位数分析 ===")
# 计算幸福分数的四分位数
happiness_quantiles = sim_df['happiness_score'].quantile(q=[0.25, 0.5, 0.75])
print("幸福分数(happiness_score)的四分位数:")
print(happiness_quantiles)
print()
# 计算人均GDP的90%分位数(较高水平阈值)
gdp_90th = sim_df['gdp_per_capita'].quantile(q=0.9)
print(f"人均GDP(gdp_per_capita)的90%分位数(前10%的高水平阈值): {gdp_90th:.3f}")
模拟国家发展指标数据集 (前5行):
      country  happiness_score  gdp_per_capita  life_expectancy region
0  Country_00             6.48           3.674             70.6   West
1  Country_01             4.43           3.052             76.4   West
2  Country_02             4.13           3.391             71.0  North
3  Country_03             5.76           4.251             66.4   East
4  Country_04             6.60           2.053             73.0   East

============================================================

=== 数据集描述性统计摘要 ===
       happiness_score  gdp_per_capita  life_expectancy
count        20.000000        20.00000        20.000000
mean          5.392500         2.70850        76.440000
std           1.165919         0.84817         5.937162
min           3.300000         1.17400        66.400000
25%           4.647500         2.08750        71.000000
50%           5.295000         2.59300        76.550000
75%           6.435000         3.43525        80.000000
max           7.900000         4.25100        87.000000

============================================================

=== 关键百分位数分析 ===
幸福分数(happiness_score)的四分位数:
0.25    4.6475
0.50    5.2950
0.75    6.4350
Name: happiness_score, dtype: float64

人均GDP(gdp_per_capita)的90%分位数(前10%的高水平阈值): 3.693

分析要点:

  1. 整体概览:describe()显示数据完整(count均为20),幸福分数平均约5.39,人均GDP平均约2.71,预期寿命平均约76.4岁。各指标均存在一定波动(std不为0)。
  2. 深入洞察:
    • 幸福分数的中位数(5.295)与均值(5.3925)接近,分布相对对称。
    • 25%的国家幸福分数低于4.6475,75%分位数为6.435(即约75%的国家低于此值、约25%高于此值),中间50%的国家分数集中在4.6475到6.435之间。
    • 人均GDP的90%分位数约为3.693,意味着约90%的国家人均GDP低于此值(只有约10%的国家超过此值),这可以作为定义“高收入”阈值的参考。

📝 动手练一练

  1. 概念辨析:假设你拿到一份某城市居民年收入的样本数据,发现收入的均值远高于中位数。请解释这可能反映了数据分布的什么特点?在实际报告中,使用哪个指标描述“典型收入”更合适?为什么?
👉 点击查看参考答案

这种情况通常表明收入数据是右偏(正偏)分布,即存在少数收入极高的个体( outliers,极端值),这些极高的收入将整体均值大幅拉高,而中位数由于对极端值不敏感,其值较低。

在描述“典型收入”或“普通居民收入”时,使用中位数更为合适。因为它代表了收入序列中间位置的值,不受少数极高收入者的影响,能更好地反映大多数居民的收入状况。均值在此场景下容易造成误解,让人们高估普通居民的实际收入水平。

  1. 代码实践:使用上面实战演练中创建的sim_df DataFrame,请编写代码计算life_expectancy(预期寿命)列的 10%分位数 和 99%分位数,并解释这两个分位数的实际意义可能是什么。
👉 点击查看参考答案
import pandas as pd
import numpy as np

# 重建数据确保自包含
np.random.seed(123)
n_countries = 20
sim_data = {
    'country': [f'Country_{i:02d}' for i in range(n_countries)],
    'happiness_score': np.round(np.random.uniform(3, 8, n_countries), 2),
    'gdp_per_capita': np.round(np.random.lognormal(1.0, 0.3, n_countries), 3),
    'life_expectancy': np.round(np.random.normal(75, 5, n_countries), 1),
    'region': np.random.choice(['North', 'South', 'East', 'West'], n_countries)
}
sim_df = pd.DataFrame(sim_data)

life_exp_quantiles = sim_df['life_expectancy'].quantile(q=[0.10, 0.99])
print("预期寿命(life_expectancy)的10%和99%分位数:")
print(life_exp_quantiles)
预期寿命(life_expectancy)的10%和99%分位数:
0.10    69.670
0.99    86.848
Name: life_expectancy, dtype: float64

意义解释:

  • 10%分位数(约69.7岁):意味着有10%的国家的预期寿命低于或等于69.7岁。这个值可以看作是预期寿命相对较低的“门槛”,用于识别需要重点关注健康改善的地区。
  • 99%分位数(约86.8岁):意味着有99%的国家的预期寿命低于或等于86.8岁,只有1%的国家预期寿命高于此值。这个值代表了极高预期寿命的水平(在本次模拟数据背景下)。

本章小结

本节我们学习了Pandas中两个核心的统计描述方法。describe()像一份“数据体检报告”,一键提供计数、中心趋势、离散度和范围等多维度信息,是探索性数据分析(EDA)的第一步。quantile()则像一把“精准的尺子”,允许我们测量数据分布中任意位置的百分位点,特别有助于理解数据的尾部特征和设置阈值。

理解四分位数和中位数的计算与意义是关键。中位数作为稳健的集中趋势度量,与均值结合观察,能帮助我们初步判断数据分布的偏斜情况,避免被极端值误导结论。

📋 行动清单

  • 对你手头或课程提供的任意一个DataFrame,运行describe()方法,观察各数值列的统计摘要,检查是否有缺失值(count < 总行数)。
  • 选择一列数据,使用quantile()计算其25%、50%、75%分位数,并与describe()的输出进行核对。
  • 思考一个你熟悉的领域(如薪资、房价、成绩),比较使用均值和中位数进行描述时可能带来的不同解读,加深对两者适用场景的理解。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 本节课件:常用统计方法(1) -- describe quantile
    PDF · 302KB
    下载
  • 全套课件打包(第1-5章)
    ZIP · 12.8MB
    下载
  • 全套课件打包(第6-8章)
    ZIP · 15MB
    下载
  • 实战数据集:AppleStore 应用商城分析
    ZIP · 329KB
    下载
  • 实战数据集:女性服装电商分析
    ZIP · 2.8MB
    下载
  • Python 数据分析环境搭建指南
    PDF · 2MB
    下载
  • Scrapy 安装教程
    PDF · 12.7MB
    下载
  • 附加实战项目:AppleStore 应用商城数据分析
    ZIP · 0.3MB · ipynb + CSV 数据
    下载
  • 附加实战项目:银行电话营销数据分析
    ZIP · 0.4MB · ipynb + CSV 数据
    下载
  • 附加实战项目:女性服装电商评论数据分析
    ZIP · 2.7MB · ipynb + CSV 数据
    下载
  • 附加实战项目:美国化学学会杂志数据分析
    ZIP · 34.2MB · ipynb + SQLite 数据库
    下载