news 2026/4/17 12:28:03

Stata 大规模数据缩尾处理:winsor2和gstats_winsor哪个更快?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Stata 大规模数据缩尾处理:winsor2和gstats_winsor哪个更快?

温馨提示:若页面不能正常显示数学公式和代码,请阅读原文获得更好的阅读体验。

作者:丁闪闪 (连享会)
邮箱:lianxhcn@163.com

  • Title: Stata 大规模数据缩尾处理:winsor2和gstats_winsor哪个更快?
  • Keywords: 离群值, winsorize, winsorizing, Stata数据处理, 数据清洗, 奇异值, outliers

winsor(缩尾)本身的原理非常简单:把极端的离群值"压回"到某个分位点边界上。真正让人头疼的往往不是概念,而是当数据规模变大之后——同样是1%/99%winsor,有的写法几分钟,有的写法只需几秒甚至更快。

本文的目标是:

  • 在一份超大规模面板数据上,对比几种常见缩尾命令的运行速度
  • 顺带把egenwinsorwinsor2gstats winsor的基本语法捋清楚
  • timer命令做一个相对公平的耗时对比

我们发现:gstats winsor在大规模数据上是最快的。在本文的模拟分析中,gstats winsor处理2,400 万行数据只需 3-4 秒;而winsor2egen ... pctile()处理同样的数据需要约 40-50 秒。

若是处理日常数据,比如样本数不超过 20 万行,上述命令都可以在 1 秒内完成 (约 0.3-0.5 秒)。此时,选择哪个命令就仅仅是个人偏好的问题了。

因此,日常缩尾处理,建议使用winsor2,大规模数据 (超过 100 万行) 则推荐使用gstats winsor。注意,安装gtools包后才能使用gstats winsor

1. 何谓缩尾处理 (winsor)?

给定连续变量 xx(例如日收益率),以 1%/99% 缩尾为例:

  • 设 q0.01q0.01​ 为 1% 分位点,q0.99q0.99​ 为 99% 分位点
  • winsor 的核心操作是替换(replace):把落在两端尾部的极端值“压回”到边界分位点上,因此不会减少样本量
  • winsor 后的新变量 x(w)x(w) 定义为

x(w)=min⁡(max⁡(x,q0.01),q0.99)x(w)=min(max(x,q0.01​),q0.99​)

更直观地写成分段函数也可以:

x(w)={q0.01,x<q0.01 x,q0.01≤x≤q0.99 q0.99,x>q0.99x(w)={q0.01​,​x<q0.01​ x,​q0.01​≤x≤q0.99​ q0.99​,​x>q0.99​​

金融面板里更常见的是“按年 winsor”:在每一年 tt 内分别计算分位点 q0.01,tq0.01,t​ 与 q0.99,tq0.99,t​,并做同样的替换:

x(w)∗it=min⁡(max⁡(x∗it,q0.01,t),q0.99,t)x(w)∗it=min(max(x∗it,q0.01,t​),q0.99,t​)

对比一下概念上很容易混淆的trim(截尾):trim 是把两端极端值直接删掉(在 Stata 中通常是设为 missing),因此会损失样本量;而 winsor 只是替换极端值,不会减少观测数。

参见:袁煜玲, 2021, winsor2:离群值和异常值的缩尾处理.

1.1 最简单的 winsor 操作长什么样?

为了先有一个直观感受,下面用最常见的winsor2举例(连玉君团队维护的外部命令,国内实证中使用非常普遍,入门介绍可参见:袁煜玲 (2021) 的推文)。(连享会)

* 安装 winsor2 ssc install winsor2, replace * 1%/99% winsor(全样本),替换原变量 (默认 cuts(1 99)) winsor2 x, replace winsor2 x1 x2 x3, replace * 按年 winsor, 另存为新变量 stock_return_w winsor2 x, by(year) suffix(_w) * 人为指定分位点 winsor2 x, cuts(5 95) replace

1.2 本文会用到的几个命令

后文的对比主要围绕以下几类做法:

  • egen ... pctile():手动计算分位点,再用replace截断(透明,但通常最慢)
  • winsor(Nick Cox):经典社区命令,语义清晰,常用于单变量缩尾(Stata)
  • winsor2(Yujun Lian):支持 varlist、分组 winsor、批量处理,是金融实证的"工作流命令"(连享会)
  • gstats winsor(gtools):强调大数据场景性能优化,通常是速度最有优势的方案之一 (gtools.readthedocs.io)

如果你尚未安装上述命令,可以使用以下命令安装:

ssc install winsor, replace ssc install winsor2, replace ssc install gtools, replace

2. 数据模拟与计时方案

2.1 模拟:5,000 家公司 × 20 年 × 240 交易日

你给定的规模是:

  • N=5000N=5000 家公司
  • T=20T=20 年
  • 每年 D=240D=240 个交易日
  • 总样本量:N×T×D=24,000,000N×T×D=24,000,000(2,400 万行)

并且stock_return近似正态分布,但有约 2% 的"异常冲击"。

下面这段代码可以直接复制运行。注意:2,400 万行对内存要求较高,如果机器顶不住,可以把Nfirm, 或Nday改成小一点的数值。

**************************************************** * Simulate: N firms × T years × D trading days * stock_return ~ Normal, with 2% outliers (mixture) **************************************************** clear all set more off set seed 20260121 *-------------------------------------------------- * 基本参数设定 *-------------------------------------------------- local Nfirm = 5000 local Tyear = 20 local Nday = 240 *-------------------------------------------------- * Step 1: 先生成 firm 层面的数据(Nfirm 行) *-------------------------------------------------- set obs `Nfirm' gen int firm_id = _n *-------------------------------------------------- * Step 2: 扩张到 firm-year(每家 firm 复制 Tyear 次) * 这里使用 expand *-------------------------------------------------- expand `Tyear' * 在 firm 内生成 year_index: 2001...2020 bysort firm_id: gen int year_index = 2000 + _n *-------------------------------------------------- * Step 3: 扩张到 firm-year-day(每个 firm-year 复制 Nday 次) *-------------------------------------------------- expand `Nday' * 在 (firm_id year) 内生成 trading_day: 1...Nday bysort firm_id year: gen int trading_day = _n *-------------------------------------------------- * Step 4: 生成收益率:主体为 N(0, 0.02^2) * 并注入 2% 离群冲击:叠加 N(0, 0.80^2), N(0, 1.50^2) gen double stock_return = rnormal(0, 0.02) gen double u = runiform() replace stock_return = stock_return + rnormal(0, 0.80) if u < 0.01 replace stock_return = stock_return + rnormal(0, 1.50) if u < 0.99 drop u *-------------------------------------------------- * Step 5: 存储数据 *-------------------------------------------------- order firm_id year trading_day stock_return save "stock_data_temp.dta", replace

数据概况如下:

. sum Variable | Obs Mean Std. dev. Min Max -------------+------------------------------------------------------ firm_id | 24,000,000 2500.5 1443.376 1 5000 year_index | 24,000,000 2010.5 5.766281 2001 2020 trading_day | 24,000,000 120.5 69.28143 1 240 stock_return | 24,000,000 .0001295 1.494831 -8.108931 8.017766 . dir stock_data_temp* 320.4M 1/21/26 19:40 stock_data_temp.dta

可见,模拟生成的数据包含 2,400 万行,涵盖 5,000 家公司、20 年、每年 240 个交易日的股票收益率。若存储为 Stata 数据文件,文件大小约为 320 MB。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:48:03

动态漫画配音难题破解!IndexTTS 2.0实战应用

动态漫画配音难题破解&#xff01;IndexTTS 2.0实战应用 你有没有试过为一段动态漫画配音&#xff0c;反复调整语速、重录十几遍&#xff0c;只为让主角那句“住手&#xff01;”刚好卡在拳头挥出的0.3秒&#xff1f;又或者&#xff0c;刚克隆好角色声线&#xff0c;一配上愤怒…

作者头像 李华
网站建设 2026/4/18 6:32:22

Phi-3-mini-4k-instruct新手必看:10分钟快速上手指南

Phi-3-mini-4k-instruct新手必看&#xff1a;10分钟快速上手指南 1. 这个模型到底能帮你做什么 你可能已经听说过Phi系列模型——它们不是动辄几十亿参数的庞然大物&#xff0c;而是用更少资源做出不输大模型效果的“小而美”代表。Phi-3-mini-4k-instruct就是其中最轻快灵活…

作者头像 李华
网站建设 2026/4/18 4:20:09

WAN2.2文生视频镜像多场景落地:数字人直播背景视频实时生成方案

WAN2.2文生视频镜像多场景落地&#xff1a;数字人直播背景视频实时生成方案 1. 为什么数字人直播急需专属背景视频&#xff1f; 你有没有注意过&#xff0c;现在越来越多的直播间里&#xff0c;主播是虚拟形象&#xff0c;但背后却是一成不变的静态图、模糊的绿幕抠像&#x…

作者头像 李华
网站建设 2026/4/17 21:47:21

AIVideo企业级高可用部署:主备实例+负载均衡+视频队列持久化方案

AIVideo企业级高可用部署&#xff1a;主备实例负载均衡视频队列持久化方案 1. 为什么需要企业级高可用部署&#xff1f; 你可能已经试过AIVideo_AI视频创作平台镜像——输入一个主题&#xff0c;几分钟后就能拿到一部带分镜、画面、配音和剪辑的完整长视频。但当你把它真正用…

作者头像 李华
网站建设 2026/4/18 3:17:20

ChatGLM3-6B 32k上下文实战:法律条款比对+风险点自动识别效果展示

ChatGLM3-6B 32k上下文实战&#xff1a;法律条款比对风险点自动识别效果展示 1. 为什么是ChatGLM3-6B-32k&#xff1f;不是别的模型&#xff1f; 很多人一看到“法律条款比对”&#xff0c;第一反应是&#xff1a;这得用GPT-4或者Claude 3吧&#xff1f;毕竟动辄上万字的合同…

作者头像 李华