【quantile函数】全方位解析:从概念到实践

在数据分析和统计学中,了解数据集的分布特征至关重要。除了均值、中位数等集中趋势指标,我们还需要工具来描述数据的离散程度和位置信息。而分位数(Quantile)就是这样一个强大的概念,它将有序数据集分割成具有相等数量数据点的连续区间。而quantile函数,则是实现分位数计算的实用工具。本文将围绕quantile函数展开,详细探讨它是什么、为什么被广泛使用、可以在哪里找到它、它的输出结果代表什么、以及如何在实际中操作使用。

什么是quantile函数?

简单来说,quantile函数是一个用于计算数据集分位数值的函数。给定一个数据集(通常是一组数值)和一个或多个介于0和1之间的分位数水平(例如,0.25、0.5、0.75),quantile函数会返回对应于这些水平的数据值。

这些分位数水平代表了数据集中低于该数值的数据所占的比例。

  • 0.5分位数:这就是我们熟悉的中位数(Median),表示有50%的数据低于或等于这个值。
  • 0.25分位数0.75分位数:与0.5分位数一起,它们被称为四分位数(Quartiles)。0.25分位数是第一四分位数(Q1),表示25%的数据低于它;0.75分位数是第三四分位数(Q3),表示75%的数据低于它。
  • 0.01分位数,0.99分位数等:常用于理解数据的极端值,例如,99%的数据低于0.99分位数。
  • 分位数乘以100就是百分位数(Percentile)。例如,0.80分位数对应于第80百分位数。

因此,quantile函数的核心作用是找到数据集中的特定“分割点”。

为什么使用quantile函数?

为什么我们需要计算分位数,以及为什么quantile函数如此有用?原因在于它提供了对数据分布更深入的理解,而不仅仅是平均值:

  • 理解数据分布的形状和离散度:通过计算四分位数(Q1, Median, Q3),我们可以快速了解数据的中心位置和中间50%数据的分布范围(即四分位距 IQR = Q3 – Q1)。IQR 对异常值不敏感,是衡量数据分散度的稳健指标。
  • 识别潜在的异常值:分位数常用于异常值检测规则中,例如,通常将低于 Q1 – 1.5*IQR 或高于 Q3 + 1.5*IQR 的数据点视为潜在的异常值。
  • 数据摘要和比较:分位数提供了一种简洁的方式来概括大型数据集。比较不同组或不同时间点的数据集的分位数,可以揭示它们分布上的差异。
  • 风险管理:在金融领域,分位数(如VaR – Value at Risk,在特定置信水平下的最大潜在损失)是评估风险的关键指标。
  • 性能评估:在某些领域(如网络延迟),平均值可能具有误导性,高分位数(如第95或99百分位数)更能反映最坏情况下的性能,这对于保证服务质量至关重要。

总而言之,quantile函数帮助我们跳出对平均值的依赖,从不同角度审视数据集,特别是在数据存在偏斜或异常值的情况下。

在哪里可以找到quantile函数?

quantile函数并不是一个独立的软件应用,而是作为功能集成在各种数据处理和统计分析环境中的函数或方法。你可以在几乎所有流行的数据科学工具和编程语言中找到它的实现:

  • 编程语言库:

    • Python:在强大的数值计算库 NumPy 中有 numpy.quantile() 函数,在数据分析库 Pandas 中,DataFrame 和 Series 对象都提供了 .quantile() 方法。这是数据科学家最常接触的场景之一。
    • R:作为统计计算的基石语言,R 的基础安装包中就包含了 quantile() 函数。
  • 统计软件:

    • 绝大多数专业的统计分析软件(如 SPSS, SAS, Stata 等)都提供了计算分位数的内置功能或过程。
  • 电子表格软件:

    • Microsoft Excel 提供了 PERCENTILE.INCPERCENTILE.EXC 等函数来计算百分位数(也就是分位数)。
    • Google Sheets 等在线表格工具也提供类似的功能。
  • 数据库系统:

    • 一些高级的数据库系统(如 PostgreSQL, Oracle, SQL Server)提供了窗口函数或聚合函数来计算分位数,例如 PERCENTILE_CONTPERCENTILE_DISC

虽然不同平台上的函数名称、参数和具体实现可能略有差异(尤其是在处理非整数分位数秩时),但核心概念和功能是一致的。

使用quantile函数“得到多少”?

使用quantile函数,你最终得到的是一个或多个具体的数值,这些数值来自于你的原始数据集的取值范围之内(或者在某些插值方法下,是范围内数值的线性组合)。

  • 如果你请求一个分位数水平(例如,0.5),函数返回一个单一数值,即中位数。
  • 如果你请求多个分位数水平(例如,[0.25, 0.5, 0.75]),函数通常返回一个包含相应分位数值的列表、数组或序列

这个“多少”不是数据的个数,也不是比例本身,而是那个具有特定“比例分割”意义的数据值

例如,对于数据集 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],如果调用 quantile(data, 0.5),你得到的“多少”是 5.5(取决于具体的计算方法,这里以一种常见方法为例,即 (5+6)/2)。这意味着数据集中有50%的值小于或等于5.5。如果你调用 quantile(data, 0.25),你可能会得到 3.25,表示25%的数据小于或等于3.25。

因此,quantile函数的输出直接对应了数据集的特定位置上的数值大小。

如何使用quantile函数?(附Python示例)

不同的环境使用quantile函数的方式略有不同。这里我们以最常用的Python中的NumPy和Pandas库为例,展示其基本用法。

在NumPy中使用 numpy.quantile()

NumPy是Python进行科学计算的基础库,提供了处理数组和矩阵的强大功能。

import numpy as np

# 创建一个示例数据集
data = np.array([1, 3, 5, 2, 4, 6, 8, 7, 9, 10])

# 计算中位数 (0.5分位数)
median_val = np.quantile(data, 0.5)
print(f”数据集: {data}”)
print(f”中位数 (0.5分位数): {median_val}”)

# 计算四分位数 (0.25, 0.5, 0.75)
quartiles = np.quantile(data, [0.25, 0.5, 0.75])
print(f”四分位数 (Q1, Median, Q3): {quartiles}”)

# 计算第90百分位数 (0.9分位数)
percentile_90 = np.quantile(data, 0.9)
print(f”第90百分位数: {percentile_90}”)

主要参数:

  • a:输入的数据数组。
  • q:要计算的分位数水平。可以是单个浮点数(0到1之间)或一个浮点数的数组/列表。
  • interpolation:指定当所需分位数位置落在两个数据点之间时的插值方法(稍后详细说明)。默认通常是 ‘linear’。

在Pandas中使用 .quantile() 方法

Pandas是构建在NumPy之上的数据结构和数据分析工具,Series和DataFrame是其核心数据结构。

import pandas as pd

# 创建一个示例 Pandas Series
s = pd.Series([1, 3, 5, 2, 4, 6, 8, 7, 9, 10])

# 计算 Series 的中位数
median_s = s.quantile(0.5)
print(f”Series: {s.tolist()}”)
print(f”Series 中位数: {median_s}”)

# 计算 Series 的四分位数
quartiles_s = s.quantile([0.25, 0.5, 0.75])
print(f”Series 四分位数:\n{quartiles_s}”)

# 创建一个示例 Pandas DataFrame
df = pd.DataFrame({‘col1’: [10, 20, 30, 40, 50],
‘col2’: [1, 2, 3, 4, 5],
‘col3’: [100, 200, 300, 400, 500]})

print(f”\nDataFrame:\n{df}”)

# 计算 DataFrame 每列的中位数 (默认 axis=0,即沿着行)
median_df_cols = df.quantile(0.5)
print(f”DataFrame 每列中位数:\n{median_df_cols}”)

# 计算 DataFrame 每行的中位数 (指定 axis=1)
median_df_rows = df.quantile(0.5, axis=1)
print(f”DataFrame 每行中位数:\n{median_df_rows}”)

# 计算 DataFrame 每列的四分位数
quartiles_df_cols = df.quantile([0.25, 0.5, 0.75])
print(f”DataFrame 每列四分位数:\n{quartiles_df_cols}”)

Pandas 的 .quantile() 方法参数:

  • q:要计算的分位数水平(单个数值或列表/数组)。
  • axis:对于 DataFrame,指定计算方向。axis=0(默认)对每列计算分位数,axis=1 对每行计算分位数。
  • interpolation:插值方法,与NumPy类似。

可以看到,无论是在NumPy数组还是Pandas数据结构上,quantile函数/方法的调用方式都非常直观,核心在于指定数据和所需的分位数水平。

quantile函数是如何工作的?(插值方法简述)

理解quantile函数的工作原理有助于解释为什么在不同工具或使用不同插值方法时,结果可能会有细微差异。

计算分位数的基本步骤如下:

  1. 排序:首先,将数据集从小到大进行排序。
  2. 确定秩(Rank)/位置:根据数据集的大小 (n) 和所需的分位数水平 (q),计算出该分位数对应的理论“秩”或位置。存在多种计算秩的公式,其中一种常见的形式是 rank = q * (n - 1) + 1。这个秩表示在排序后的数据中,这个分位数对应的元素应该处于哪个位置(从1开始计数)。
  3. 取值或插值:

    • 如果计算出的秩是整数,那么该分位数的值就是排序后的数据集中对应秩位置的元素值。
    • 如果计算出的秩不是整数(例如,3.25),这意味着所需的分位数位于两个数据点之间。此时就需要进行插值(Interpolation)

插值是计算分位数时最容易产生差异的地方。不同的插值方法会根据秩的小数部分以及相邻数据点的值来确定最终的分位数值。NumPy和Pandas提供了多种插值选项,包括:

  • ‘linear’ (线性插值):这是最常用的默认方法。如果秩是 `i + f`,其中 `i` 是整数部分,`f` 是小数部分,则分位数的值计算为 `(1 – f) * value_at_rank_i + f * value_at_rank_i+1`。
  • ‘lower’:取秩位置向下取整的元素值。
  • ‘higher’:取秩位置向上取整的元素值。
  • ‘nearest’:取秩位置最近的整数秩对应的元素值。
  • ‘midpoint’:取秩位置向下和向上取整对应的两个元素值的平均值。

例如,对于排序后的数据集 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (n=10),计算0.25分位数。秩 = 0.25 * (10 – 1) + 1 = 0.25 * 9 + 1 = 2.25 + 1 = 3.25。

  • 如果使用 ‘linear’ 插值,结果会在排序后第3个值 (3) 和第4个值 (4) 之间,按比例 (1 – 0.25) * 3 + 0.25 * 4 = 0.75 * 3 + 0.25 * 4 = 2.25 + 1 = 3.25。
  • 如果使用 ‘lower’,结果将是第3个值,即 3。
  • 如果使用 ‘higher’,结果将是第4个值,即 4。

了解这一点有助于解释为何来自不同软件或不同参数设置的同一分位数计算结果可能略有差异。在大多数标准数据分析场景中,线性插值 (‘linear’) 是一个合理的默认选择。

如何理解quantile函数的结果?

理解quantile函数的结果,就是将输出的数值与其对应的分位数水平联系起来。

假设你计算了数据集的0.1分位数是15,0.5分位数是50,0.9分位数是120。这意味着:

  • 约有10%的数据值小于或等于15。
  • 约有50%的数据值小于或等于50(中位数)。
  • 约有90%的数据值小于或等于120。

通过这些数值,你可以推断:

  • 数据的集中趋势大致在50附近。
  • 数据从15到120涵盖了绝大多数(中间80%)的数据。
  • 15以下和120以上的数据相对较少,它们可能是数据的尾部或潜在的异常值。

如果你比较两个不同群体(例如,A组和B组学生的考试分数)的分位数:

A组分数 0.25分位数: 60, 0.5分位数: 75, 0.75分位数: 85
B组分数 0.25分位数: 65, 0.5分位数: 80, 0.75分位数: 90

你可以得出结论:B组学生的整体分数分布高于A组,因为B组的各个分位数都高于A组。B组的中间50%分数(65到90)也高于A组的中间50%分数(60到85)。

因此,理解quantile函数的结果,就是利用这些分位数数值来剖析数据的结构、分布、离散度以及与其他数据集进行有意义的比较。它提供了一种稳健且直观的方式来把握数据集的整体情况,尤其是在数据分布不均匀或存在极端值时。


quantile函数