C++代码实现MATLAB中的removeoutliers函数功能
// removeoutliers.cpp// 对应 MATLAB rmoutliers(A) 的 C++ 实现 + 演示程序// 编译: g++ -std=c++17 -O2 -o removeoutliers_demo#include<iostream>#include<iomanip>#include<vector>#include<algorithm>#include<cmath>#include<numeric>#include<stdexcept>#include<string>/** * 对应 MATLAB rmoutliers(A) 的 C++ 实现 * 默认方法:MAD(中位数绝对偏差),阈值因子 3 * 支持方法:median(MAD)、mean(均值±标准差)、quartiles(四分位数) */classRemoveOutliers{public:// 检测方法enumclassMethod{Median,// 默认,MADMean,// 均值 ± 3σQuartiles// 四分位数法};structOptions{Method method=Method::Median;doublethresholdFactor=3.0;// median/mean 默认 3;quartiles 默认 1.5booluseScaledMAD=true;// 是否使用换算 MAD(乘常数 c)intdim=1;// 1 按行移除,2 按列移除(矩阵)};structResult{std::vector<std::vector<double>>cleanedData;// 清洗后数据std::vector<bool>outlierMask;// 离群值逻辑掩码(展平)std::vector<int>removedIndices;// 被移除的行/列索引};public:/** * 对向量或矩阵进行离群值检测与移除 * @param data 输入数据(二维:行×列) * @param opts 选项 * @return 清洗后的数据及元信息 */staticResultprocess(conststd::vector<std::vector<double>>&data){returnprocess(data,Options{});}staticResultprocess(conststd::vector<std::vector<double>>&data,constOptions&opts){if(data.empty()||data[0].empty())throwstd::invalid_argument("Input data is empty.");constsize_t rows=data.size();constsize_t cols=data[0].size();// 校验:所有行长度一致for(constauto&row:data){if(row.size()!=cols)throwstd::invalid_argument("Rows have inconsistent lengths.");}Result result;if(opts.dim==1){// 按列检测,移除整行(MATLAB 默认行为)result=processByColumn(data,opts);}elseif(opts.dim==2){// 按行检测,移除整列result=processByRow(data,opts);}else{throwstd::invalid_argument("dim must be 1 or 2.");}returnresult;}// ========== 核心统计函数 ==========/** * 计算中位数(自动排序副本,不修改原数据) */staticdoublemedian(std::vector<double>v){if(v.empty())return0.0;size_t n=v.size();std::sort(v.begin(),v.end());if(n%2==1){returnv[n/2];}else{return0.5*(v[n/2-1]+v[n/2]);}}/** * 计算换算 MAD(Median Absolute Deviation) * scaledMAD = c * median(|x - median(x)|) * c = 1 / (sqrt(2) * erfcinv(3/2)) ≈ 1.482602218505602 */staticdoublescaledMAD(conststd::vector<double>&data){if(data.size()<2)return0.0;doublemed=median(data);std::vector<double>absDev;absDev.reserve(data.size());for(doublex:data){absDev.push_back(std::fabs(x-med));}doublerawMAD=median(absDev);// 换算常数 cconstdoublec=1.482602218505602;returnc*rawMAD;}/** * 计算算术均值 */staticdoublemean(conststd::vector<double>&data){if(data.empty())return0.0;doublesum=std::accumulate(data.begin(),data.end(),0.0);returnsum/static_cast<double>(data.size());}/** * 计算样本标准差(无偏估计,除以 n-1,与 MATLAB std 默认一致) */staticdoublestddev(conststd::vector<double>&data){size_t n=data.size();if(n<2)return0.0;doublem=mean(data);doublesqSum=0.0;for(doublex:data){doubled=x-m;sqSum+=d*d;}returnstd::sqrt(sqSum/static_cast<double>(n-1));}/** * 计算指定百分位数(线性插值法,与 MATLAB prctile 一致) */staticdoublepercentile(std::vector<double>v,doublep){if(v.empty())return0.0;if(p<=0.0)return*std::min_element(v.begin(),v.end());if(p>=100.0)return*std::max_element(v.begin(),v.end());std::sort(v.begin(),v.end());doublerank=(p/100.0)*(static_cast<double>(v.size())-1.0);size_t lo=static_cast<size_t>(std::floor(rank));size_t hi=static_cast<size_t>(std::ceil(rank));doublefrac=rank-static_cast<double>(lo);if(lo==hi)returnv[lo];returnv[lo]*(1.0-frac)+v[hi]*frac;}private:// ========== 按列处理(移除行) ==========staticResultprocessByColumn(conststd::vector<std::vector<double>>&data,constOptions&opts){constsize_t rows=data.size();constsize_t cols=data[0].size();std::vector<bool>rowOutlier(rows,false);// 对每一列独立检测for(size_t j=0;j<cols;++j){std::vector<double>colData;colData.reserve(rows);for(size_t i=0;i<rows;++i)colData.push_back(data[i][j]);std::vector<bool>colMask=detectOutliers(colData,opts);for(size_t i=0;i<rows;++i){if(colMask[i])rowOutlier[i]=true;// 任一列检出则移除整行}}// 构建结果Result res;res.outlierMask=rowOutlier;for(size_t i=0;i<rows;++i){if(rowOutlier[i]){res.removedIndices.push_back(static_cast<int>(i));}else{res.cleanedData.push_back(data[i]);}}returnres;}// ========== 按行处理(移除列) ==========staticResultprocessByRow(conststd::vector<std::vector<double>>&data,constOptions&opts){constsize_t rows=data.size();constsize_t cols=data[0].size();std::vector<bool>colOutlier(cols,false);for(size_t i=0;i<rows;++i){std::vector<bool>rowMask=detectOutliers(data[i],opts);for(size_t j=0;j<cols;++j){if(rowMask[j])colOutlier[j]=true;}}Result res;for(size_t i=0;i<rows;++i){std::vector<double>newRow;for(size_t j=0;j<cols;++j){if(!colOutlier[j])newRow.push_back(data[i][j]);}res.cleanedData.push_back(std::move(newRow));}for(size_t j=0;j<cols;++j){if(colOutlier[j])res.removedIndices.push_back(static_cast<int>(j));}res.outlierMask=colOutlier;returnres;}// ========== 离群值检测核心 ==========staticstd::vector<bool>detectOutliers(conststd::vector<double>&data,constOptions&opts){size_t n=data.size();std::vector<bool>mask(n,false);if(n<2)returnmask;switch(opts.method){caseMethod::Median:{doublemed=median(data);doublemadVal=opts.useScaledMAD?scaledMAD(data):[&](){std::vector<double>absDev;for(doublex:data)absDev.push_back(std::fabs(x-med));returnmedian(absDev);}();if(madVal<=0.0)returnmask;// 所有值相同,无离群值doublethr=opts.thresholdFactor*madVal;for(size_t i=0;i<n;++i){if(std::fabs(data[i]-med)>thr)mask[i]=true;}break;}caseMethod::Mean:{doublem=mean(data);doubles=stddev(data);if(s<=0.0)returnmask;doublethr=opts.thresholdFactor*s;for(size_t i=0;i<n;++i){if(std::fabs(data[i]-m)>thr)mask[i]=true;}break;}caseMethod::Quartiles:{doubleq1=percentile(data,25.0);doubleq3=percentile(data,75.0);doubleiqr=q3-q1;doublelower=q1-opts.thresholdFactor*iqr;doubleupper=q3+opts.thresholdFactor*iqr;for(size_t i=0;i<n;++i){if(data[i]<lower||data[i]>upper)mask[i]=true;}break;}}returnmask;}};// ============================ 演示主程序 ============================intmain(){// 示例数据(含离群值)std::vector<std::vector<double>>data={{1.0,1.0},// 0{34.0,0.0},// 1{35.0,35.0},// 2{35.0,35.0},// 3{33.0,33.0},// 4{34.0,34.0},// 5{160.0,160.0},// 6 离群值{38.0,38.0},// 7{35.0,35.0},// 8{95.0,35.0},// 9 第1列离群{36.0,36.0},// 10{150.0,150.0},// 11 离群值{39.0,39.0},// 12{41.0,41.0},// 13{42.0,40.0},// 14{0.0,0.0},// 15 离群值{200.0,200.0}// 16 离群值};// 默认 MAD 方法autoresult=RemoveOutliers::process(data);std::cout<<"=== 默认 MAD 方法(thresholdFactor=3)===\n";std::cout<<"被移除的行索引:";for(intidx:result.removedIndices)std::cout<<idx<<" ";std::cout<<"\n\n清洗后数据:\n";for(constauto&row:result.cleanedData){for(doublev:row)std::cout<<std::setw(6)<<v<<" ";std::cout<<"\n";}// 均值 ± 3σ 方法RemoveOutliers::Options meanOpt;meanOpt.method=RemoveOutliers::Method::Mean;autoresultMean=RemoveOutliers::process(data,meanOpt);std::cout<<"\n=== Mean 方法 ===\n移除行数:"<<resultMean.removedIndices.size()<<"\n";// 四分位数方法RemoveOutliers::Options quartOpt;quartOpt.method=RemoveOutliers::Method::Quartiles;quartOpt.thresholdFactor=1.5;autoresultQuart=RemoveOutliers::process(data,quartOpt);std::cout<<"\n=== Quartiles 方法(1.5×IQR)===\n移除行数:"<<resultQuart.removedIndices.size()<<"\n";return0;}

相关新闻

原生JavaScript表单与搜索框组件库:防抖、校验与本地存储实战解析

原生JavaScript表单与搜索框组件库:防抖、校验与本地存储实战解析

简介&#xff1a;6个精美的Web前端表单提交与搜索框示例&#xff0c;是一份面向初中级前端开发者、UI设计师及网站后台维护人员的实用参考。压缩包内含完整的表单与搜索页面源码&#xff0c;将CSS样式与jQuery脚本集中在HTML示例中&#xff0c;覆盖文本框、下拉菜单、复选框等常…

2026/10/21 6:03:25 阅读更多 →
基于PySpark+Hive+大模型的小红书评论情感分析与舆情预测系统设计

基于PySpark+Hive+大模型的小红书评论情感分析与舆情预测系统设计

动手做毕业设计的时候&#xff0c;能同时把PySpark、Hive、大模型这三个词凑到一个题目里&#xff0c;本身就说明这个题目不是那种随便改个爬虫就能糊弄的“水货”。小红书评论情感分析、笔记可视化、舆情预测&#xff0c;这套组合拳打下来&#xff0c;技术栈覆盖了数据采集、分…

2026/10/21 6:03:25 阅读更多 →
MySQL索引从原理到实战:B+树、执行计划与慢SQL调优

MySQL索引从原理到实战:B+树、执行计划与慢SQL调优

刚接手一个线上系统的时候&#xff0c;我遇到过一条查询跑两秒多的SQL&#xff0c;全表扫描扫了三百多万行&#xff0c;而业务要求响应在一百毫秒内。当时的我连EXPLAIN都不会看&#xff0c;被DBA指着鼻子说"你这表连索引都没建对"。从那以后&#xff0c;我把MySQL索…

2026/10/21 6:03:25 阅读更多 →

最新新闻

大语言模型训练全流程解析:从Token到SFT与RLHF的工程实践

大语言模型训练全流程解析:从Token到SFT与RLHF的工程实践

1. 先建立整体坐标系&#xff1a;LLM的四大训练阶段与核心概念地图聊大语言模型之前&#xff0c;我觉得最重要的事不是急着看某个公式或者某个库的API&#xff0c;而是先把整个训练流程的“地图”装进脑子里。很多人一上来就盯着“上下文窗口”“Token”这些名词逐个查&#xf…

2026/10/21 6:59:47 阅读更多 →
知识工作插件化:从设计逻辑到工程落地的完整实践指南

知识工作插件化:从设计逻辑到工程落地的完整实践指南

1. 从"知识工作插件"这个命名说起&#xff1a;它到底在解决什么问题第一次看到 knowledge-work-plugins 这个命名&#xff0c;我的直觉是&#xff1a;这不是一个具体的工具&#xff0c;而是一类架构思路的统称。它指向的是把"知识工作"这件事拆解成可插拔、…

2026/10/21 6:59:47 阅读更多 →
深度学习训练诊断:从梯度消失到激活漂移的排查实践

深度学习训练诊断:从梯度消失到激活漂移的排查实践

一开始接触深度神经网络的时候&#xff0c;我最大的困惑不是“它能不能学”&#xff0c;而是“它到底是怎么学出来的”。前面几篇我们聊了网络结构、损失函数、正则化这些基础零件&#xff0c;但真到了调模型的时候你会发现&#xff0c;真正拉开差距的往往不是模型的骨架&#…

2026/10/21 6:59:47 阅读更多 →
储能与虚拟电厂收益关键:预测系统可信度如何构建

储能与虚拟电厂收益关键:预测系统可信度如何构建

最近这段时间&#xff0c;储能和虚拟电厂几乎成了能源行业最热的两条赛道&#xff0c;各种项目发布会、示范工程、聚合平台路演一个接一个。但圈内人私下聊起来&#xff0c;真正关心的不是谁的电池容量大、谁的界面做得炫&#xff0c;而是同一个问题&#xff1a;项目到底能不能…

2026/10/21 6:59:46 阅读更多 →
告别通用模板:答辩PPT的场景化应用策略拆解

告别通用模板:答辩PPT的场景化应用策略拆解

每到毕业季&#xff0c;答辩现场的“翻车”方式总是千奇百怪&#xff1a;有人PPT做得像产品发布会&#xff0c;评委想看的数据却一页都没有&#xff1b;有人内容明明很扎实&#xff0c;却因为版式太乱、逻辑断层&#xff0c;被误判为“准备不充分”&#xff1b;还有人开场就念稿…

2026/10/21 6:59:46 阅读更多 →
Linux网络学习【传输层协议UDP】

Linux网络学习【传输层协议UDP】

&#x1f525;承渊政道&#xff1a;个人主页 ❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C知识内容》 《Linux系统与网络知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》 《MySQL数据库学习》 《Python知识内容》 《cpolar知识学习》 ✨…

2026/10/21 6:58:46 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →