news 2026/9/3 8:44:58

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/9/2 22:16:42

Clawdbot Web网关直连Qwen3-32B:低成本GPU算力方案与推理加速技巧

Clawdbot Web网关直连Qwen3-32B&#xff1a;低成本GPU算力方案与推理加速技巧 1. 为什么需要“直连网关”这种部署方式&#xff1f; 你有没有遇到过这种情况&#xff1a;想用Qwen3-32B做本地智能对话&#xff0c;但一开模型就卡住——显存爆了、响应慢得像在等煮面、部署流程…

作者头像 李华
网站建设 2026/9/3 5:56:38

零基础玩转WuliArt Qwen-Image Turbo:4步生成1024×1024高清图

零基础玩转WuliArt Qwen-Image Turbo&#xff1a;4步生成10241024高清图 1. 为什么这款文生图工具值得你立刻试试&#xff1f; 你有没有过这样的经历&#xff1a;想为公众号配一张赛博朋克风格的封面&#xff0c;却卡在“怎么描述才让AI懂”&#xff1b;想给小红书做一组国风…

作者头像 李华
网站建设 2026/9/2 19:50:17

从零实现工业电机控制:Proteus元件对照表操作指南

以下是对您提供的博文内容进行 深度润色与结构重构后的技术文章 。全文已彻底去除AI生成痕迹,强化了工程师视角的实战语感、教学逻辑与工程直觉;摒弃所有模板化标题与刻板段落,代之以自然流畅、层层递进的技术叙事;关键概念加粗突出,代码注释更贴近真实调试场景,并补充…

作者头像 李华
网站建设 2026/9/2 22:22:21

小白必看:GPEN照片修复镜像保姆级使用教程

小白必看&#xff1a;GPEN照片修复镜像保姆级使用教程 1. 这不是修图软件&#xff0c;是你的AI照片修复助手 你有没有遇到过这些情况&#xff1a; 翻出十年前的老照片&#xff0c;满是噪点、模糊不清&#xff0c;想发朋友圈却不敢发&#xff1f;家里长辈的结婚照泛黄起皱&am…

作者头像 李华
网站建设 2026/9/2 9:55:57

5大关键指标,全面评估AI原生应用的可用性

5大关键指标&#xff0c;全面评估AI原生应用的可用性关键词&#xff1a;AI原生应用、可用性评估、智能交互、任务准确率、自适应学习摘要&#xff1a;随着ChatGPT、Midjourney等AI原生应用的爆发式增长&#xff0c;如何判断一个AI应用“好不好用”成了用户和开发者共同关心的问…

作者头像 李华
网站建设 2026/9/3 2:00:43

5步搞定GLM-4-9B-Chat-1M部署:vLLM推理+Chainlit前端实战

5步搞定GLM-4-9B-Chat-1M部署&#xff1a;vLLM推理Chainlit前端实战 本文面向希望快速落地超长上下文大模型能力的开发者与技术团队&#xff0c;聚焦一个开箱即用的镜像方案——【vllm】glm-4-9b-chat-1m。它不是从零编译的理论教程&#xff0c;而是一套已预装、已调优、可直接…

作者头像 李华