图片数据清洗

2023-05-16

前言

数据对于深度学习算法模型的效果至关重要。通常,在对采集到的大量数据进行标注前需要做一些数据清洗工作。对于大量的数据,人工进行直接清洗速度会很慢,因此开发一些自动化清洗工具对批量数据首先进行自动清洗,然后再进行人工审核并清洗,可以很大程度上提高效率。

工具功能

根据收集到的需求,工具主要实现了以下功能:

  • 统计数据信息(总占用空间、数量、损坏图片数);
  • 去除已损坏图片,
  • 去除模糊图片,
  • 去除相似图片,
  • 机动车车色分类,
  • 昼夜分类

统计数据信息

# 获取数据集存储大小、图片数量、破损图片数量
def get_data_info(dir_path):
    size = 0
    number = 0
    bad_number = 0
    for root, dirs, files in os.walk(dir_path):
        img_files = [file_name for file_name in files if is_image(file_name)]
        files_size = sum([os.path.getsize(os.path.join(root, file_name)) for file_name in img_files])
        files_number = len(img_files)
        size += files_size
        number += files_number
        for file in img_files:
            try:
                img = Image.open(os.path.join(root, file))
                img.load()
            except OSError:
                bad_number += 1
    return size / 1024 / 1024, number, bad_number

去除已损坏图片

# 去除已损坏图片
def filter_bad(dir_path):
    filter_dir = os.path.join(os.path.dirname(dir_path), 'filter_bad')
    if not os.path.exists(filter_dir):
        os.mkdir(filter_dir)
    filter_number = 0
    for root, dirs, files in os.walk(dir_path):
        img_files = [file_name for file_name in files if is_image(file_name)]
        for file in img_files:
            file_path = os.path.join(root, file)
            try:
                Image.open(file_path).load()
            except OSError:
                shutil.move(file_path, filter_dir)
                filter_number += 1
    return filter_number

去除模糊图片

首先需要判断图片的清晰度,用opencv提供的拉普拉斯算子接口求得清晰度数值,数值越小,清晰度越低,也就越模糊(通常以100位分界值)。

# 去除模糊图片
def filter_blurred(dir_path):
    filter_dir = os.path.join(os.path.dirname(dir_path), 'filter_blurred')
    if not os.path.exists(filter_dir):
        os.mkdir(filter_dir)
    filter_number = 0
    for root, dirs, files in os.walk(dir_path):
        img_files = [file_name for file_name in files if is_image(file_name)]
        for file in img_files:
            file_path = os.path.join(root, file)
            # img = cv2.imread(file_path)
            img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
            image_var = cv2.Laplacian(img, cv2.CV_64F).var()
            if image_var < 100:
                shutil.move(file_path, filter_dir)
                filter_number += 1
    return filter_number

还有很多图像模糊检测的方法,可以参考:https://www.cnblogs.com/greentomlee/p/9379471.html

去除相似图片

对于一些通过视频抽帧得到的图片数据,连续图片相似度会很高,需要剔除相似度较高的图片数据。
首先我们需要计算两张图片的相似度,计算相似度的方法通常有以下几种:

  • 通过直方图计算图片的相似度;
  • 通过哈希值,汉明距离计算;
  • 通过图片的余弦距离计算;
  • 通过图片的结构度量计算。

四种方法结果可能会不同。
参考:https://blog.csdn.net/weixin_35132022/article/details/112514520
下面是利用python opencv中通过直方图计算图片的相似度。去除相似图片过程通过遍历求每张图片和它之后的四张图片(这里比较之后的几张可以根据实际需求调整)的相似度,如果相似度超过阈值则剔除后面的图片。

# 计算两张图片的相似度
def calc_similarity(img1_path, img2_path):
    img1 = cv2.imdecode(np.fromfile(img1_path, dtype=np.uint8), -1)
    H1 = cv2.calcHist([img1], [1], None, [256], [0, 256])  # 计算图直方图
    H1 = cv2.normalize(H1, H1, 0, 1, cv2.NORM_MINMAX, -1)  # 对图片进行归一化处理
    img2 = cv2.imdecode(np.fromfile(img2_path, dtype=np.uint8), -1)
    H2 = cv2.calcHist([img2], [1], None, [256], [0, 256])  # 计算图直方图
    H2 = cv2.normalize(H2, H2, 0, 1, cv2.NORM_MINMAX, -1)  # 对图片进行归一化处理
    similarity1 = cv2.compareHist(H1, H2, 0)  # 相似度比较
    print('similarity:', similarity1)
    if similarity1 > 0.98:  # 0.98是阈值,可根据需求调整
        return True
    else:
        return False

# 去除相似度高的图片
def filter_similar(dir_path):
    filter_dir = os.path.join(os.path.dirname(dir_path), 'filter_similar')
    if not os.path.exists(filter_dir):
        os.mkdir(filter_dir)
    filter_number = 0
    for root, dirs, files in os.walk(dir_path):
        img_files = [file_name for file_name in files if is_image(file_name)]
        filter_list = []
        for index in range(len(img_files))[:-4]:
            if img_files[index] in filter_list:
                continue
            for idx in range(len(img_files))[(index+1):(index+5)]:
                img1_path = os.path.join(root, img_files[index])
                img2_path = os.path.join(root, img_files[idx])
                if calc_similarity(img1_path, img2_path):
                    filter_list.append(img_files[idx])
                    filter_number += 1
        for item in filter_list:
            src_path = os.path.join(root, item)
            shutil.move(src_path, filter_dir)
    return filter_number

机动车车色分类

方法一:传统算法(结果不理想)

使用opencv库函数进行处理。

1、将图片颜色转为hsv,
2、使用cv2.inRange()函数进行背景颜色过滤
3、将过滤后的颜色进行二值化处理
4、进行形态学腐蚀膨胀,cv2.dilate()
5、统计白色区域面积
参考:https://www.jb51.net/article/172797.htm

# 定义HSV颜色字典
def get_color_list():
    dict = collections.defaultdict(list)
    # 黑色
    lower_black = np.array([0, 0, 0])
    upper_black = np.array([180, 255, 46])
    color_list = []
    color_list.append(lower_black)
    color_list.append(upper_black)
    dict['black'] = color_list

    # 灰色
    # lower_gray = np.array([0, 0, 46])
    # upper_gray = np.array([180, 43, 220])
    # color_list = []
    # color_list.append(lower_gray)
    # color_list.append(upper_gray)
    # dict['gray'] = color_list

    # 白色
    lower_white = np.array([0, 0, 221])
    upper_white = np.array([180, 30, 255])
    color_list = []
    color_list.append(lower_white)
    color_list.append(upper_white)
    dict['white'] = color_list

    # 红色1
    lower_red = np.array([156, 43, 46])
    upper_red = np.array([180, 255, 255])
    color_list = []
    color_list.append(lower_red)
    color_list.append(upper_red)
    dict['red'] = color_list

    # 红色2
    lower_red = np.array([0, 43, 46])
    upper_red = np.array([10, 255, 255])
    color_list = []
    color_list.append(lower_red)
    color_list.append(upper_red)
    dict['red2'] = color_list

    # 橙色
    lower_orange = np.array([11, 43, 46])
    upper_orange = np.array([25, 255, 255])
    color_list = []
    color_list.append(lower_orange)
    color_list.append(upper_orange)
    dict['orange'] = color_list

    # 黄色
    lower_yellow = np.array([26, 43, 46])
    upper_yellow = np.array([34, 255, 255])
    color_list = []
    color_list.append(lower_yellow)
    color_list.append(upper_yellow)
    dict['yellow'] = color_list

    # 绿色
    lower_green = np.array([35, 43, 46])
    upper_green = np.array([77, 255, 255])
    color_list = []
    color_list.append(lower_green)
    color_list.append(upper_green)
    dict['green'] = color_list

    # 青色
    lower_cyan = np.array([78, 43, 46])
    upper_cyan = np.array([99, 255, 255])
    color_list = []
    color_list.append(lower_cyan)
    color_list.append(upper_cyan)
    dict['cyan'] = color_list

    # 蓝色
    lower_blue = np.array([100, 43, 46])
    upper_blue = np.array([124, 255, 255])
    color_list = []
    color_list.append(lower_blue)
    color_list.append(upper_blue)
    dict['blue'] = color_list

    # 紫色
    lower_purple = np.array([125, 43, 46])
    upper_purple = np.array([155, 255, 255])
    color_list = []
    color_list.append(lower_purple)
    color_list.append(upper_purple)
    dict['purple'] = color_list

    return dict

# 颜色识别
def get_color(image):
    print('go in get_color')
    img_array = cv2.imdecode(np.fromfile(image, dtype=np.uint8), -1)
    kernel_4 = np.ones((4, 4), np.uint8)  # 4x4的卷积核
    hsv = cv2.cvtColor(img_array, cv2.COLOR_BGR2HSV)
    maxsum = -100
    color = None
    color_dict = get_color_list()
    print(color_dict)
    for key in color_dict:
        mask = cv2.inRange(hsv, color_dict[key][0], color_dict[key][1]) # mask是把HSV图片中在颜色范围内的区域变成白色,其它区域变成黑色
        cv2.imwrite(key + os.path.splitext(image)[-1], mask)
        erosion = cv2.erode(mask, kernel_4, iterations=1)
        erosion = cv2.erode(erosion, kernel_4, iterations=1)
        dilation = cv2.dilate(erosion, kernel_4, iterations=1)
        dilation = cv2.dilate(dilation, kernel_4, iterations=1)
        target = cv2.bitwise_and(img_array, img_array, mask=dilation)
        binary = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY)[1]
        # binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
        # binary = cv2.dilate(binary, None, iterations=2)
        cnts, hiera = cv2.findContours(binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # cnts, hiera = cv2.findContours(binary.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        sum = 0
        for c in cnts:
            sum += cv2.contourArea(c)
        if sum > maxsum:
            maxsum = sum
            color = key
    return color
方法二:深度学习模型

采用训练好的针对机动车ROI图像颜色分类模型,效果好太多了。

# 对机动车ROI图片按颜色分类
def classify_vehcolor(dir_path):
    result_dir = os.path.join(os.path.dirname(dir_path), 'color_results')
    if not os.path.exists(result_dir):
        os.mkdir(result_dir)
    color_list = dict_color.values()
    for color in color_list:
        color_dir = os.path.join(result_dir, color)
        if not os.path.exists(color_dir):
            os.mkdir(color_dir)
    classify_number = 0
    for root, dirs, files in os.walk(dir_path):
        for dir in dirs:
            result_dic = classify_color(os.path.join(root, dir))
            for key, value in result_dic.items():
                dst_path = os.path.join(result_dir, value)
                try:
                    shutil.move(key, dst_path)
                    classify_number += 1
                except Exception:
                    pass
        img_files = [file_name for file_name in files if is_image(file_name)]
        if len(img_files) != 0:
            result_dic = classify_color(root)
            for key, value in result_dic.items():
                dst_path = os.path.join(result_dir, value)
                try:
                    shutil.move(key, dst_path)
                    classify_number += 1
                except Exception:
                    pass
    return classify_number

昼夜分类

即对图片拍摄场景是白天还是黑夜进行分类。这里采用求图片的平均亮度进行粗略分类,经实测,准确率不高,但目前先采用该方法进行初步清洗吧,后续有时间再寻求更优算法。

# 对图片进行昼夜分类,根据图片的平均亮度
def classify_day_or_night(dir_path):
    result_dir = os.path.join(os.path.dirname(dir_path), 'day_night_results')
    if not os.path.exists(result_dir):
        os.mkdir(result_dir)
    item_list = ['白天', '黑夜']
    for item in item_list:
        item_dir = os.path.join(result_dir, item)
        if not os.path.exists(item_dir):
            os.mkdir(item_dir)
    classify_number = 0
    for root, dirs, files in os.walk(dir_path):
        img_files = [file_name for file_name in files if is_image(file_name)]
        for file in img_files:
            file_path = os.path.join(root, file)
            rgb_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
            img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2GRAY)
            brightness_value = img.mean()
            print('brightness_value', brightness_value)
            if brightness_value > 95:
                key = '白天'
            else:
                key = '黑夜'
            dst_path = os.path.join(result_dir, key)
            try:
                shutil.move(file_path, dst_path)
                classify_number += 1
            except Exception:
                pass
    return classify_number

工具界面展示

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图片数据清洗 的相关文章

  • Python 自学笔记

    前言 此Python3笔记仅为本人自学网络教学视频总结的笔记 xff0c 初衷仅为个人的学习和复习使用 xff0c 本人使用的编译器为Pycharm xff0c 内容仅供参考 xff08 俺是小白 xff0c 有不对的地方希望各位大佬指出
  • libcli工具的使用-命令行修改输入参数

    libcli工具的使用 命令行修改输入参数 libcli工具介绍 Libcli 提供了一个共享的 C 库 xff0c 用于将类似 Cisco 的命令行界面包含到其他软件中 它是一个 telnet 接口 xff0c 支持用户可定义的功能树的命
  • STM32无法连接JLink(Flash读写保护) 解决方法

    By Ailson Jack Date 2020 12 12 个人博客 xff1a 首页 说好一起走 本文在我博客的地址是 xff1a STM32无法连接JLink Flash读写保护 解决方法 说好一起走 xff0c 排版更好 xff0c
  • Softmax到AMSoftmax(附可视化代码和实现代码)

    Softmax nbsp 个人理解 在训练的时候 加上角度margin 把预测出来的值减小 往0那里挤压 离标注距离更大 减少训练得分 加大loss 增加训练收敛难度 不明白的有个问题 减去m后 如果出现负数怎么办 nbsp nbsp 以下
  • linux python保存mp4

    解决 python调用OpenCV 保存视频时使用 avc1 格式出现 Could not find encoder for codec id 27 Encoder not found的错误 此错误不能保存视频文件 以及使用 mpeg 格式
  • 在树莓派4B安装 scipy 笔记,不需要删除numpy,不需要mkl

    在树莓派4B安装 scipy 笔记 xff0c 不需要删除numpy xff0c 不需要mkl 参考官网 xff1a 不要用sudo xff0c 带上 user xff0c 否则有问题 xff0c 官网 最好用pip安装 python sp
  • LINUX基础试题大全(4)

    说明 xff1a 此文章由于题数庞大 xff0c 为方便阅读本人将其分为四篇文章为大家分享 xff01 答案会今后不断进行更新 xff01 LINUX基础试题大全 xff08 1 xff09 填空题题 LINUX基础试题大全 xff08 2
  • Oracle 创建用户

    span class token comment 查看表空间 span span class token keyword select span span class token operator span span class token
  • Win10 (mstsc)局域网远程桌面连接,超全面设置。(附带,外网远程连接mstsc)

    TCP IP xff08 Transmission Control Protocol Internet Protocol xff0c 传输控制协议 网际协议 xff09 是指能够在多个不同网络间实现信息传输的协议簇 TCP IP协议不仅仅指
  • postgresql |数据库 |数据库的常用备份方法总结

    前言 xff1a 数据库的重要性就不需要在这里重复了 xff0c 那么 xff0c 不管是测试环境 xff0c 还是开发环境 xff0c 亦或者是生产环境 xff0c 数据库作为系统内 xff08 项目内 xff09 的一个非常重要的组件
  • USB连接到centos7虚拟机出现错误(VMware USB Arbitration Service无法启动)

    USB连接到centos7虚拟机出现错误 有可能是因为VMware USB Arbitration Service出现无法自启动的问题 windows主机中WIN 43 R打开运行界面 xff0c 输入 接着查看VMware USB Arb
  • Centos7下配置网卡网桥

    简介 xff1a Linux系统下开启虚拟机需要配置网桥 xff0c 从而使得Linux系统里虚拟化软件的虚拟交换机与宿主机的物理网卡绑定一起 虚拟机与宿主机互相独立的IP 物理网卡监听这些IP xff0c 从而达到虚拟机与物理机在同一个局
  • 【玩转cocos2d-x之二十五】数据结构CCArray

    原创作品 xff0c 转载请标明 xff1a http blog csdn net jackystudio article details 16938787 CCArray是从cocos2d中移植过来的 xff0c 类似于Apple的NSM
  • 5、钉钉平台

    文章目录 文章目录 应用管理运行环境应用类型编程模式风神工作台基础应用信息接口权限应用发布 钉钉集成参数设置钉钉接口地址常量 钉钉集成登录钉钉事件回调接口注册通讯录事件回调群会话事件回调签到事件回调审批事件回调 日志管理签到事件回调审批事件
  • CentOS常用防火墙命令

    systemctl启动 停止 查看防火墙状态 systemctl从CentOS7 x开始引入的一个服务管理工具命令 xff0c 集 service和chkconfig的功能于一体 启动防火墙 systemctl start firewall
  • ARDUINO LCD显示简单的汉字、符号(二 已写成的字模和基于Python的检索系统)

    北 61 0x0A 0x0A 0x0A 0x1B 0x0A 0x0A 0x0A 0x1B 京 61 0x04 0x1F 0x0E 0x0A 0x0E 0x15 0x15 0x0C 市 61 0x04 0x1F 0x04 0x1F 0x15
  • MindSpore图像分类训练resnet50实现

    目录 一 mindspore简介 二 训练环境 三 数据集与数据加载 四 模型训练和验证 五 迁移学习 六 模型测试和导出 一 mindspore简介 MindSpore 是华为开源的全场景深度学习框架 xff0c 旨在实现易开发 高效执行
  • 最快的远程控制软件radmin的配置和使用

    Remote Administrator Radmin 是最快的远程控制软件 又因为它不被杀毒软件查杀 从而成为远程控制的首选 nbsp 一 radmin的配置 首先下载并解压Radmin2 1 解压后有七个文件 打开 配置r server
  • 介绍一个成功的 Git 分支模型

    英文原文 xff0c A successful Git branching model xff0c 翻译 xff1a 开源中国 在这篇文章中 xff0c 我提出一个开发模型 我已经将这个开发模型引入到我所有的项目里 xff08 无论在工作还
  • 浪潮服务器通过BMC远程安装系统

    浪潮服务器的BMC xff0c 类似于IBM服务器的IPMI xff0c 可以远程安装系统或者其他操作 前提 xff1a 1 带外ip xff1a 192 168 1 100 在bios的 lan channel 1 里面配置带外ip xf

随机推荐

  • Linux|错误集锦|prometheus Error on ingesting samples that are too old or are too far into the future的解决

    前情回顾 xff1a 二进制prometheus部署完成后 xff0c 在prometheus的web界面进行一些数据验证工作 下面这个是我已经恢复正常的 xff0c 其实是查询不到数据的 grafana也接收不到任何数据 问题排查 xff
  • 《软件工程导论》/ 第一章 软件工程学概述 / 1.3 软件生命周期

    概括地说 xff0c 软件生命周期由3个时期组成 xff0c 每个时期又进一步划分成若干个阶段 xff1a 软件定义 xff08 问题定义 可行性研究 需求分析 xff09 软件开发 xff08 总体设计 详细设计 编码和单元测试 综合测试
  • python开发PC端桌面应用

    项目场景 xff1a 很多情况下需要用很短的时间开发一款在windows上离线运行的小工具 xff0c 以便解决一些现实问题 比如公司近期有个紧急项目 xff0c 需要根据算法需求人工标注海量的地址信息 xff0c 开发周期和工具易用性上都
  • Vue和Flask实现前后端分离

    引言 近期了解了下目前比较热门的前端框架Vue js xff0c 新技能嘛 xff0c 只有实践了用起来了 xff0c 才能有比较直观的体验 因此考虑写个小demo练练手 xff0c 后端采用Flask提供几个Restfull风格的API
  • C/S架构的应用程序开发实战(一)

    项目背景 近期需要开发一个对巨量的图片数据进行车辆品牌信息标注的工具 xff0c 为了提高标注效率 xff0c 准备先通过现有车辆品牌识别的算法模型进行下预标注 xff0c 标注人员在此基础上进行审核和修改即可 另外 xff0c 需要统计出
  • Nginx服务安全漏洞修复

    1 安全漏洞说明 使用Nginx提供服务的产品 xff0c 经过安全扫描工具扫描后报出三个高风险 三个中风险安全漏洞 2 nginx版本过低自带安全漏洞 升级nginx版本到1 21 1后 xff0c 三个高风险漏洞消失 3 HTTP 信息
  • C/S架构的应用程序开发实战(二)

    后端服务 后端用python实现 xff0c 采用flask web框架 可从github上获取flasky源码 xff0c 在此基础上进行业务逻辑的实现 程序结构如下 xff1a app 业务逻辑实现代码 common 公共函数实现 这里
  • MySql安装相关

    windows安装mysql xff1a 1 获取并解压安装包 xff1a mysql 8 0 20 winx64 zip 2 配置环境变量 xff1a 3 管理员权限打开cmd xff0c 进入安装目录 xff1a H gt cd H t
  • MySql之索引

    通常小型项目涉及数据量比较小 xff0c 数据查询频率不高 xff0c 索引通常会被忽略 但当数据量较大 xff0c 涉及多个表 xff0c 查询较为频繁时 xff0c 我们需要对查询性能进行优化 xff0c 此时 xff0c 建立合适的索
  • jupyter-notebook二次开发

    背景 公司内部提供给算法人员用于模型训练的平台开发需求中提出了嵌入Jupyter Notebook模块 xff0c 而Jupyter Notebook是开源的 xff0c 方便后续对部分细节进行功能定制和优化 xff0c 需要对其进行调研
  • python中大数据文件读取

    python中大数据文件读取 python中经常会遇到读取大文件的场景 文件较小时 xff0c 我通常采用下面方法 xff0c readlines xff08 xff09 xff0c 该方法会一次性读取文件的所有行 xff0c 并将其放入l
  • Linux|奇怪的知识|locate命令---文件管理小工具

    前言 Linux的命令是非常多的 xff0c 有一些冷门的命令 xff0c 虽然很少用 xff0c 但可能会有意想不到的功能 xff0c 例如 xff0c 本文将要介绍的locate命令 xff08 平常很少会想到使用此命令 xff0c f
  • python之装饰器

    引言 软件开发中 xff0c 当需要创建高度重复的代码时 xff0c 需要寻求一种优雅的解决方案 python中的元编程即解决这类问题 xff0c 通过创建函数和类来修改 生成或包装已有的代码 装饰器就是python中用来包装函数的一种机制
  • docker容器中程序退出异常,GPU未释放

    1 问题描述 近期在docker容器中对一批数据通过算法进行清洗时 xff0c 当数据处理完成后发现进程未正常退出 xff0c GPU内存未正常释放 span class token punctuation span root 64 ai6
  • 初识Redis

    什么是Redis Remote Dictionary Server xff0c 即远程字典服务 xff0c 是一款开源的 基于内存也支持持久化的key value数据库 xff0c 提供多种语言API 通常应用于需要处理大规模数据读写的场景
  • python之闭包

    前言 闭包作为python高级特性中的一个 xff0c 初学总觉其披着一层神秘的面纱 xff0c 这里我们来一起揭开这层面纱吧 那什么是闭包呢 xff1f 闭包 xff0c 又称闭包函数 xff0c 和普通的嵌套函数类似 xff0c 闭包中
  • 三个基础排序算法

    排序在计算机算法中非常常见也非常基础 xff0c 不管是准备面试还是纯属兴趣 xff0c 掌握它都很有必要 选择排序 基本思想 xff1a 预置list i 为最小 xff0c 逐个比较range i len list 里的元素 xff0c
  • 数据结构之链表

    和顺序表相对应 xff0c 有个链式存储的数据结构 xff0c 命名曰链表 单链表 节点中只存储后项节点指针的链表 xff0c 称为单链表 定义节点 class LinkNode object def init self data 61 N
  • 数据结构之哈希表

    概念 哈希表是一种数据结构 xff0c 通过哈希函数来组织数据 xff0c 以支持快速插入和搜索 哈希表的关键思想是使用哈希函数将键映射到存储桶 更确切地说 xff0c 当我们插入一个新的键时 xff0c 哈希函数将决定该键应该分配到哪个桶
  • 图片数据清洗

    前言 数据对于深度学习算法模型的效果至关重要 通常 xff0c 在对采集到的大量数据进行标注前需要做一些数据清洗工作 对于大量的数据 xff0c 人工进行直接清洗速度会很慢 xff0c 因此开发一些自动化清洗工具对批量数据首先进行自动清洗