掌握这些技巧,让Excel批量数据清洗变得简单高效!
什么是数据清洗
数据清洗是指在数据处理过程中对原始数据进行筛选、转换和修正,以确保数据的准确性、一致性和完整性的过程。它是数据预处理的一部分,旨在处理和纠正可能存在的错误、缺失值、异常值和不一致性等数据质量问题。
为什么要数据清洗
Excel在数据采集场景中非常常用。作为一款电子表格软件,它提供了丰富的功能和易用的界面,使其成为大部分人首选的数据采集工具之一。
而在数据采集的过程中,因为采集渠道多样,数据格式也多种多样,从而会出现部分数据的丢失和不准确的情况,因此为了处理掉这些 “垃圾”数据,需要对数据进行清洗。
哪些数据需要进行清洗
通常在这几种情况下需要进行数据清洗。
1.缺失数据处理:数据在采集或迁移的过程中,出现数据的遗漏。
2.错误数据判断:数据在采集或迁移的过程中与原数据不一致。
3.重复数据处理:一条数据重复出现多次。
4.数据格式转换:数据在采集或迁移的过程中出现了乱码。
数据清洗都需要做些什么
下面让我们看一下数据清洗都会涉及的处理步骤:
- 分析需求:通过对数据原本的格式,特征进行分析,规划数据清洗的业务规则及需求。
- 打开文件:把Excel文件打开,通常这一步需要依赖Excel组件库,比如使用POI,GcExcel,EasyExcel等。
- 读取数据:通过Excel库中的API,读取需要操作的数据,这里比较一下三个产品的特点:
GcExcel提供了**IRange(区域)**的概念,可以通过API快速的读取有数据的区域。POI和EasyExcel(POJO注解)则需要遍历每一个单元格。
根据业务需求,可以选择使用API,也可以选择遍历所有单元格。
- 数据清洗:根据需求,结合Excel库的API,进行数据清洗。如:用默认值填写缺失数据的单元格,删除整个空行,删除重复数据,把不符合范围的数据删除掉,或者把日期数字的格式统一起来,等等。
- 数据持续化:把处理好的数据回存至Excel文件,或者保存在数据库中或者CSV文件中。
如何使用GcExcel实现数据清洗
GcExcel有IRange的API,可以让数据清洗时代码写的更简单,因此下面我们选择用GcExcel的代码为例解决上面提到的几个场景。
基于IRange,GcExcel提供一些快速查找的API,如下(在文件中查找特殊单元格):
Workbook workbook = new Workbook();workbook.open("data.xlsx");IWorksheet sheet = workbook.getActiveSheet();//寻找sheet中,使用到的所有单元格IRange usedRange = sheet.getUsedRange();//寻找所有的公式单元格IRange allFormulas = sheet.getCells().specialCells(SpecialCellType.Formulas);//寻找所有的常量单元格IRange allConstants = sheet.getCells().specialCells(SpecialCellType.Constants);
虽然GcExcel提供了API,但数据清洗时,也可能有需求需要遍历,下面是GcExcel遍历单元格的代码,后面我们就有可能会用到。
public void FetchCellBasedOnRange(IRange area) {for (int column = 0; column < area.getColumns().getCount(); column++) {for (int row = 0; row < area.getRows().getCount(); row++) {IRange cell = area.get(row, column);//获取单元格的值Object val = cell.getValue();}}}
场景一:缺失数据处理
假如有一个Excel的数据,现在蓝色的格子是空的,我们需要对不同列下的蓝色格子做不同的处理,例如姓名的空格子替换为匿名,年龄替换成-1,身份证号填写N/A,住址填写为未知。

代码如下:
public void replaceBlankCell() {Workbook workbook = new Workbook();workbook.open("resources/BlankCells.xlsx");IWorksheet sheet = workbook.getActiveSheet();IRange blankRanges = sheet.getCells().specialCells(SpecialCellType.Blanks);for (IRange area : blankRanges.getAreas()) {for (int column = 0; column < area.getColumns().getCount(); column++) {for (int row = 0; row < area.getRows().getCount(); row++) {IRange cell = area.get(row, column);Object defaultVal = getDefaultVal(cell.getColumn());cell.setValue(defaultVal);}}}workbook.save("Result.xlsx");}private Object getDefaultVal(int column) {switch (column) {case 1:return "匿名";case 2:return -1;case 3:return "N/A";case 4:return "未知";}return null;}

要注意的是,sheet.getCells().specialCells(SpecialCellType.Blanks);返回的区域是多个,因此我们需要遍历通过遍历areas来对每一个区域进行遍历。
cell.getColumn()可以获取到当前格子对应到sheet上的第几列,因此获取默认值时使用该方法。
场景二:错误数据判断
错误数据的判断,与缺失数据处理相似,通过制定一些规则找出错误的值,对于错误值可以通过修改背景颜色进行高亮处理,用来提示,进行人工修改。
通常规则可以有两种选择:
- 使用Java直接编写判断逻辑。
- 使用数据校验(Datavalidation)功能,或者条件格式(ConditionFormat)来进行处理。
假如我们有下面一份数据,其中联系电话中有两条是错误的,位数不够,货物ID有两条是错误的,货物ID不能小于0,我们需要把他们找出来。

public void MarkErrorData(){Workbook workbook = new Workbook();workbook.open("resources/ErrorData.xlsx");IWorksheet sheet = workbook.getActiveSheet();IRange telRange = sheet.getRange("C2:D5");for (int r=0; r<telRange.getRows().getCount();r++){IRange cell = telRange.get(r,0);if(cell.getValue().toString().length() != 11){cell.getInterior().setColor(Color.GetOrangeRed());}}IFormatCondition condition =(IFormatCondition) sheet.getRange("D2:D5").getFormatConditions().add(FormatConditionType.CellValue, FormatConditionOperator.Less, 1, null);condition.getInterior().setColor(Color.GetOrangeRed());workbook.save("Result.xlsx");}

在代码中,我们对C2:C5进行遍历,判断字符串长度,然后对长度不合法的数据进行颜色标记。
而对于货物,设置了条件格式,可以让Excel在打开时,自行标记错误的数据。
场景三:重复数据处理
假如我们有一份数据,其中有一些行数据是完全重复的,我们需要删除这些行,如图所示。

public void RemoveDuplicateData() {Workbook workbook = new Workbook();workbook.open("resources/DuplicateRows.xlsx");IWorksheet sheet = workbook.getActiveSheet();IRange usedRange = sheet.getUsedRange();HashSet<String> set = new HashSet<>();Stack<IRange> deleteRows = new Stack<>();for (int r = 1; r < usedRange.getRows().getCount(); r++) {IRange row = usedRange.getRows().get(r);StringBuilder rowKey = new StringBuilder();for (int c = 0; c < row.getColumns().getCount(); c++) {rowKey.append(usedRange.get(r, c).getValue().toString());}if (set.contains(rowKey.toString())) {deleteRows.push(row);} else {set.add(rowKey.toString());}}while (!deleteRows.isEmpty()) {deleteRows.pop().delete();}workbook.save("Result.xlsx");}

可以看到,重复的行被移除掉了。代码中用到了哈希set和栈,其中我们用哈希set来查找重复的行。
另外使用栈来记录需要被删除的行,这里特地用了栈,而没有使用队列,数组或者ArraryList的原因是,GcExcel在删除一行时,会让这行下面的数据上移,这样我们之前记录的行就会便宜,导致删除错误的行。
简而言之,我们需要从下向上删除,来避免行位移导致删错的问题。
场景四:数据格式转换
例如我们有一些日期数据,或者货币数据,在数据采集时数据格式不同,我们需要分别统一订单日期,金额的格式。

代码如下:
public void unifyFormat() {Workbook workbook = new Workbook();workbook.open("resources/DifferentFormat.xlsx");IWorksheet sheet = workbook.getActiveSheet();IRange usedRange = sheet.getUsedRange();for (int row = 1; row < usedRange.getRows().getCount(); row++) {IRange dateCell = usedRange.get(row, 1);IRange priceCell = usedRange.get(row, 2);dateCell.setValue(parseDate(dateCell.getValue()));dateCell.setNumberFormat("yyyy年MM月dd日");priceCell.setValue(parsePrice(priceCell.getValue()));priceCell.setNumberFormat("¥0.00");}sheet.getRange("B1").setNumberFormat("");workbook.save("Result.xlsx");}private Double parsePrice(Object value) {if (value == null)return null;String val = value.toString();if (val.startsWith("$") || val.startsWith("¥")) {val = val.substring(1);}return Double.parseDouble(val);}private LocalDateTime parseDate(Object value) {if (value == null)return null;if (value instanceof LocalDateTime) {return (LocalDateTime) value;}DateTimeFormatter[] formatters = {DateTimeFormatter.ofPattern("yyyy/MM/dd"),DateTimeFormatter.ofPattern("MM-dd-yyyy"),DateTimeFormatter.ofPattern("yyyy年MM月dd日"),DateTimeFormatter.ofPattern("yyyy.MM.dd")};LocalDate datetime = null;for (DateTimeFormatter formatter : formatters) {try {datetime = LocalDate.parse(value.toString(), formatter);break;} catch (DateTimeParseException e) {e.printStackTrace();}}assert datetime != null;return datetime.atStartOfDay();}

需要注意的是在处理日期和金额时,由于value的类型不太一致,需要写特定的方法来进行处理。
扩展链接:
Spring Boot框架下实现Excel服务端导入导出
项目实战:在线报价采购系统(React +SpreadJS+Echarts)
React + Springboot + Quartz,从0实现Excel报表自动化
相关文章:
掌握这些技巧,让Excel批量数据清洗变得简单高效!
什么是数据清洗 数据清洗是指在数据处理过程中对原始数据进行筛选、转换和修正,以确保数据的准确性、一致性和完整性的过程。它是数据预处理的一部分,旨在处理和纠正可能存在的错误、缺失值、异常值和不一致性等数据质量问题。 为什么要数据清洗 Exce…...
成都瀚网科技:抖音上线地方方言自动翻译功能
为了让很多方言的地域历史、文化、习俗能够以短视频的形式生产、传播和保存,解决方言难以被更多用户阅读和理解的问题,平台正式上线推出当地方言自动翻译功能。创作者可以利用该功能,将多个方言视频“一键”转换为普通话字幕供大众观看。 具体…...
【k8s】【docker】web项目的部署
yaml配置文件 后端:springboot项目 前端:vue项目,之前镜像封装的nginx.conf反向代理配置直接使用了docker-compose.yml中services的名称,无法代理成功,可修改为127.0.0.1 # 后端 apiVersion: apps/v1 kind: Deployment…...
【视频去噪】基于全变异正则化最小二乘反卷积是最标准的图像处理、视频去噪研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
链表经典面试题(六)
判断链表是否有环 1.题目2.思路分析(文字)3.详细的注释和代码实现 1.题目 2.思路分析(文字) 3.详细的注释和代码实现 public class Solution {public boolean hasCycle(ListNode head) {//定义两个快慢指针ListNode fast head;ListNode slow head;//让快指针走两步,慢指针走…...
SM2签名算法中随机数K的随机性对算法安全的影响
一、构造如下SM2签名算法过程1 Sig1 r1 F2BFC778C66127C74E3613FAA1AB6E207059740B317597A78BBFCDF58AED0A51 Sig1 s1 4FC719D00334CCC23098036DEEAA71DB464A076EFA79283389D3414D70659E88 私钥d B3124DC843BB8BA61F035A7D0938251F5DD4CBFC…...
郁金香2021年游戏辅助技术中级班(六)
郁金香2021年游戏辅助技术中级班(六) 055-ce,xdbg调试分析接任务交任务完成任务056-C,C写代码测试接任务交任务完成任务我们再来分析一下完成任务 057-C,C写代码测试交任务完成任务 055-ce,xdbg调试分析接任务交任务完成任务 创建一个新角色,…...
毛玻璃员工卡片悬停效果
效果展示 页面结构组成 通过效果展示图,我们可以看出页面布局比较常规,最核心的就是卡片,当鼠标没有悬停在卡片上时,文字和头像处于半透明状态,当鼠标悬停在卡片上是,底部会展示社交图标。 CSS 知识点 b…...
闪存工作原理
前言 1、闪存类型 闪存有两种分类,NAND型闪存主要用于存储 2、MOS的特性 MOS管的三个引脚分别是Gate(G)、Source(S)和Drain(D)。Gate(G)引脚是晶闸管的控制引脚&…...
从0到一配置单节点zookeeper
我的软件: 链接:https://pan.baidu.com/s/1nImkjOgzPkgaFOuUPwd1Sg?pwd2wqo 提取码:2wqo 视频教程p1-zookeeper安装和配置以及启动服务和检测是否运行成功_哔哩哔哩_bilibili 一、安装zookeeper http://zookeeper.apache.org/releases.h…...
【JVM】第三篇 JVM对象创建与内存分配机制深度剖析
目录 一. JVM对象创建过程详解1. 类加载检查2. 分配内存2.1 如何划分内存?2.2 并发问题3. 初始化4. 设置对象头5. 执行<init>方法二. 对象头和指针压缩详解三. JVM对象内存分配详解四.逃逸分析 & 栈上分配 & 标量替换详解1. 逃逸分析 & 栈上分配2. 标量替换…...
【信创】麒麟v10(arm)-mysql8-mongo-redis-oceanbase
Win10/Win11 借助qume模拟器安装arm64麒麟v10 前言 近两年的国产化进程一直在推进,基于arm架构的国产系统也在积极发展,这里记录一下基于麒麟v10arm版安装常见数据库的方案。 麒麟软件介绍: 银河麒麟高级服务器操作系统V10 - 国产操作系统、银河麒麟、中…...
maven settings.xml文件(包含了配置阿里云镜像)
mac 的 settings.xml 我配置的位置是: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml 然后 local repository 我配置的位置是: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/repos…...
分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测
分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结…...
Redis是否要分库的实践
Redis的分库其实没有带来任何效率上的提升,只是提供了一个命名空间,而这个命名空间可以完全通过key的设计来避开这个问题。 一个优雅的Redis的key的设计如下...
String 进阶
字符串拼接 // 常量与常量的拼接结果放在常量池 // 常量池中不会存在相同的常量 String str1 "a" "b"; System.out.println(str1 "ab");// 拼接时有一个为变量,则结果会放在堆中。 // 变量拼接的原理是 StringBuilder append 最后…...
ESP32设备通信-两个ESP32间UART通信
两个ESP32间UART通信 文章目录 两个ESP32间UART通信1、UART介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将使用 Arduino IDE 的 UART 硬件库在两个 ESP32 板之间执行 UART 或串行通信。 要使用 USB 端口调试和编程 ESP32,需要使用称为通用异步接收器/发送器 (UART) 通…...
LCR 052.递增顺序搜索树
题目来源: leetcode题目,网址:LCR 052. 递增顺序搜索树 - 力扣(LeetCode) 解题思路: 中序遍历时修改指针即可。 解题代码: /*** Definition for a binary tree node.* public class TreeNo…...
Mysql集群技术问答
前提:Mysql集群服务部署到一个群组的所有服务器上,一般20台为一个群组,群组内所有节点数据实时同步,动态自动维护节点。 问:集群空间跟传统空间的最大不同是什么? 答:集群空间有数据同步和宕机检…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
