0

0

深入理解 SciPy 中的截尾均值 trim_mean 函数

碧海醫心

碧海醫心

发布时间:2025-11-17 11:43:27

|

817人浏览过

|

来源于php中文网

原创

深入理解 scipy 中的截尾均值 trim_mean 函数

`scipy.stats.trim_mean` 函数用于计算截尾均值,其关键在于 `proportiontocut` 参数指定的是从排序后的样本两端截去的*观测值比例*,而非基于统计百分位数。当截取比例导致非整数个观测值时,函数会向下取整,即截去更少的观测值。理解这一机制对于正确应用该函数至关重要,尤其是在处理小样本数据时。

截尾均值概述

截尾均值(Trimmed Mean),也称为截断均值或修剪均值,是一种统计量,通过从数据集的两端移除一定比例的极端值(异常值)后,再计算剩余数据的算术平均值。这种方法能够有效地降低异常值对均值的影响,提供一个比传统算术均值更具鲁棒性的中心趋势度量。

scipy.stats.trim_mean 的工作原理

scipy.stats.trim_mean 函数的核心在于其 proportiontocut 参数的解释。许多用户可能会误以为此参数是根据数据的统计百分位数(例如,去除低于5%和高于95%的数据点)来截取数据。然而,scipy.stats.trim_mean 的实际行为是:它从排序后的样本两端截去指定比例的观测值数量

具体来说,如果样本大小为 N,proportiontocut 为 p,则函数会从数据的最小值端和最大值端各截去 floor(p * N) 个观测值。这里的 floor 函数表示向下取整。这意味着,如果 p * N 的结果是一个非整数,函数将截去比预期数量更少的(或零个)观测值。

让我们通过一个具体的例子来理解这一点:

from scipy.stats import trim_mean
import numpy as np

data = [1, 2, 2, 3, 4, 30, 4, 4, 5]
# 排序后的数据为:[1, 2, 2, 3, 4, 4, 4, 5, 30]
print(f"原始数据: {data}")
print(f"数据长度: {len(data)}")

trim_percentage = 0.05  # 截取5%

# 计算应截取的观测值数量
# 0.05 * 9 = 0.45
# floor(0.45) = 0
# 因此,从两端各截取0个观测值
result = trim_mean(data, trim_percentage)
print(f"使用 trim_mean(data, {trim_percentage}) 的结果: {result}")
print(f"普通均值: {np.mean(data)}")

输出结果:

码上飞
码上飞

码上飞(CodeFlying) 是一款AI自动化开发平台,通过自然语言描述即可自动生成完整应用程序。

下载
原始数据: [1, 2, 2, 3, 4, 30, 4, 4, 5]
数据长度: 9
使用 trim_mean(data, 0.05) 的结果: 6.111111111111111
普通均值: 6.111111111111111

在这个例子中,由于 0.05 * 9 = 0.45,向下取整后为 0,这意味着 trim_mean 从两端各截去了 0 个观测值。因此,其结果与未截取的普通均值完全相同。

行为验证:截取比例与样本量的关系

为了进一步验证这一行为,我们可以观察当 proportiontocut 刚好跨越 1/len(data) 阈值时的变化。

from scipy import stats
import numpy as np

x = [1, 2, 2, 3, 4, 30, 4, 4, 5]
n = len(x) # n = 9
p_threshold = 1 / n # 1/9 约等于 0.1111

# 当 proportiontocut 略小于 1/9 时
# 0.1111 - epsilon => 0.1111 * 9 - epsilon => 1 - epsilon
# floor(1 - epsilon) = 0
result_less = stats.trim_mean(x, p_threshold - 1e-15)
print(f"trim_mean(x, {p_threshold}-eps): {result_less}") # 仍为普通均值

# 当 proportiontocut 略大于或等于 1/9 时
# 0.1111 + epsilon => 0.1111 * 9 + epsilon => 1 + epsilon
# floor(1 + epsilon) = 1
# 此时,从排序后的数据 [1, 2, 2, 3, 4, 4, 4, 5, 30] 中,
# 两端各截去1个观测值,即移除 1 和 30。
# 剩余数据为 [2, 2, 3, 4, 4, 4, 5]
# 其均值为 (2+2+3+4+4+4+5) / 7 = 24 / 7 ≈ 3.42857
result_more = stats.trim_mean(x, p_threshold + 1e-15)
print(f"trim_mean(x, {p_threshold}+eps): {result_more}")

输出结果:

trim_mean(x, 0.1111111111111111-eps): 6.111111111111111
trim_mean(x, 0.1111111111111111+eps): 3.4285714285714284

这个示例清晰地展示了 trim_mean 依据截取比例 p 和样本量 N 计算 floor(p*N) 来确定截去观测值数量的机制。

与基于百分位数的截取均值对比

用户有时期望的“截尾”是基于数据的统计百分位数,例如去除低于第5百分位数和高于第95百分位数的所有数据。这种方法与 scipy.stats.trim_mean 的行为是不同的。

以下是手动实现基于百分位数截取均值的示例:

import numpy as np

data = [1, 2, 2, 3, 4, 30, 4, 4, 5]

# 计算5th和95th百分位数
p5, p95 = np.percentile(data, [5, 95])
print(f"\n5th 百分位数 = {p5}")
print(f"95th 百分位数 = {p95}")

# 根据百分位数筛选数据
trimmed_data_percentile = [x for x in data if p5 < x < p95]
print(f"基于百分位数截取后的数据: {trimmed_data_percentile}")

# 计算筛选后数据的均值
trimmed_average_percentile = np.mean(trimmed_data_percentile)
print(f"基于百分位数截取的均值 = {trimmed_average_percentile}")

输出结果:

5th 百分位数 = 1.4
95th 百分位数 = 19.999999999999993
基于百分位数截取后的数据: [2, 2, 3, 4, 4, 4, 5]
基于百分位数截取的均值 = 3.4285714285714284

可以看到,基于百分位数截取的均值 3.42857 与 scipy.stats.trim_mean 在 proportiontocut 足够大(例如 1/len(data) + eps)时得到的结果相同。这是因为在这个特定的数据集中,移除一个最小观测值和一个最大观测值恰好与移除超出5%和95%百分位数的数据点(1.4和19.999...之间)大致吻合。然而,这并非普遍规律,两种截取方式在概念上和具体实现上是不同的。

SciPy 库目前没有直接提供基于百分位数范围进行数据截取的函数。如果需要这种行为,用户通常需要结合 numpy.percentile 和列表推导或 filter 函数自行实现。

注意事项与最佳实践

  1. 理解 proportiontocut 的精确含义:始终记住它指定的是从排序后的样本两端截去的观测值数量比例,而非基于分布的百分位数。
  2. 小样本量影响:对于小样本数据集,proportiontocut 即使设置得较小,也可能因为 floor(p * N) 的结果为零,导致实际上没有任何数据被截取。在这种情况下,trim_mean 的结果将与普通均值相同。
  3. 自定义需求:如果您的截尾需求是基于数据的统计百分位数(例如,去除分布尾部的特定百分位点),则需要自定义实现,结合 numpy.percentile 进行数据筛选。
  4. 文档查阅:在使用任何统计函数时,查阅官方文档是最佳实践,以确保对参数和行为有准确的理解。

总结

scipy.stats.trim_mean 是一个用于计算截尾均值的有用工具,但在使用时必须明确其 proportiontocut 参数的工作机制。它通过从排序后的数据两端移除固定数量(由比例和样本量决定)的观测值来实现截尾,而非基于统计百分位数。对于需要根据百分位数进行截尾的场景,用户应考虑自行实现或寻找其他库中提供的功能。正确理解并应用这一机制,将有助于更准确地处理异常值并获得更稳健的统计结果。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

391

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

135

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

233

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

8

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

13

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

10

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

24

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

124

2026.01.26

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

98

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.0万人学习

ASP 教程
ASP 教程

共34课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号