ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

植物大全数据集导入与清洗实战:SQL/JSON/CSV处理指南

植物大全数据集导入与清洗实战:SQL/JSON/CSV处理指南 简介该数据集是一份专门面向植物爱好者、园艺工作者及科研人员的多格式植物信息库。内容涵盖观花、观叶、多肉及流行植物等常见类别每条记录包含植物名称、科属、生长环境、花期、花色与图片链接等关键字段支持按属性进行筛选、查询与识别。资源共四个文件压缩包约二点四兆由SQL数据库、JSON元数据、CSV通用表格和XLSX电子表格组成分别满足关系型查询、程序解析、跨平台交换及Excel可视化等不同使用需求。目前已有862人学习下载既有现成的结构化数据可直接导入MySQL或其他分析工具也可直接打开Excel查看和编辑。借助这套多格式组合读者可快速搭建植物查询系统、制作花期花色对照表或用于教学演示、科普展板及园艺设计参考兼顾专业研究与兴趣学习是植物数据落地应用的实用基础包。1. 植物大全数据集先搞清楚你拿到的是“数据库文件”而不是“图片包”“数据库文件-植物大全数据集”是我被问得最多的一类资源很多人以为下载后是几千张植物图片打开发现是个几百 MB 的数据库文件就不知道怎么下手了。实际上这份数据的价值不在图片而在结构化整理好的植物名录——通常包含标准名、别名、科属、分类、用途、生长习性和图片路径等字段文件格式常见 SQL、JSON、CSV 三种。它最直接的用途是给植物检索、科普展示、课程设计里的增删改查功能当底库也能作为训练分类模型前的类别清单来源。适合几类人急着给项目灌数据的开发者、做植物或鸟类识别方向课程设计的学生、想学数据库和数据集配合使用的新手。先别管图片把数据库文件用对这才是复现的第一步。2. 表结构与三种格式SQL、JSON、CSV 到底哪个适合你拿到这类数据集第一件事不是急着写查询而是先认清数据结构。植物数据集的字段设计会直接决定你后面做检索、清洗、标注有多顺手。常见做法是把所有植物信息集中在主表里字段大体一致但版本之间会有少量差异。2.1 主表结构与关键字段一份植物大全数据通常会长成下面这样不同版本字段名可能略有区别字段名类型说明idINTEGER主键唯一编号nameTEXT植物标准名比如“银杏”aliasTEXT别名多个之间一般用逗号分隔familyTEXT所在科比如“银杏科”genusTEXT所在属比如“银杏属”categoryTEXT分类标签乔木/灌木/草本/藤本usageTEXT用途标签如“药用”“观赏”“食用”originTEXT原产地或主要分布区habitTEXT生长习性如耐寒、喜光、耐阴image_pathTEXT图片路径可能为空或仅存文件名descriptionTEXT形态描述常用于展示和检索摘要created_atDATETIME记录插入时间最容易让人迷惑的字段是 image_path。它可能存的是完整 URL、相对路径也可能什么都没存。如果你打算做图片加载得先确认这个字段到底存的是什么别直接拼进前端。2.2 SQL、JSON、CSV 三种格式怎么选同一份数据发布者通常会按不同格式压缩。三种格式各有适用场景我的建议是能直接用 SQL 的不要自己写解析脚本。格式打开方式典型用途主要坑SQLNavicat、MySQL、SQLite、命令行直接导入数据库保留表结构和数据文件开头常带 DROP TABLE执行前要注意JSONPython json 模块、VSCode、各类编辑器给后端接口、小程序直接读取嵌套深度不一别名和用途字段可能缺键CSVExcel、WPS、pandas快速查看、数据清洗、数据库同步工具迁移中文编码容易乱字段值里可能夹着逗号如果你只是做演示项目SQL 版是首选导入后就能做增删改查。如果是要写代码读取JSON 比 CSV 省事因为 CSV 没有嵌入字段类型数字、空值得自己猜。CSV 更适合用数据库同步工具做增量迁移或者在 Excel 里人工核对数据。2.3 数据质量与字段边界别把这份数据当成绝对权威。我打开过几个版本都有同样的问题同一植物重复出现别名里混着学名usage 字段为空科属命名不规范比如“银杏科”和“银杏”混用。这类问题不影响看数据但会影响做统计和训练。领域数据集的常态就是“能用但脏”先把预期放低后面清洗步骤会用到。如果后续要用它做检索系统或给识别类项目当基础数据建议先按第 4 章的方式查一遍分布再做清洗否则跑到一半才发现字段是空的会很被动。3. 数据导入本地从 SQLite 到 MySQL 的完整路径了解结构之后实际動手把数据导入本地。我一般建议新手先走 SQLite因为它不需要安装服务一个文件就是整个数据库。等确认结构和数据没问题再迁到 MySQL 供多人或 Web 项目使用。3.1 用 SQLite 最快打开拿到 .db、.sqlite、.sqlite3 后缀的文件直接用 Python 自带模块就能打开import sqlite3 db_path plant_database.db conn sqlite3.connect(db_path) cur conn.cursor() # 查看这个数据库里到底有哪些表 cur.execute(SELECT name FROM sqlite_master WHERE typetable) tables cur.fetchall() print(表列表:, tables) # 统计主表的数据量 cur.execute(SELECT COUNT(*) FROM plant_info) total cur.fetchone()[0] print(plant_info 总记录数:, total) # 抽样看一眼前 10 行 cur.execute(SELECT id, name, family, genus, category FROM plant_info LIMIT 10) for row in cur.fetchall(): print(row) conn.close()这段代码里sqlite_master 是 SQLite 的系统表专门存表结构信息connect 参数指向你的 db 文件路径。如果打开后找不到 plant_info先执行第一条查询打印的表列表里找实际表名再替换代码里的表名即可。COUNT 统计的是记录总数LIMIT 10 控制抽样行数这些是数据导入后最基础的三步验证。3.2 往 MySQL 导入如果你的项目是给多人用的 Web 系统SQLite 的单机特性不够用就得迁移到 MySQL。拿到 .sql 文件后先建库再导入mysql -uroot -p -e CREATE DATABASE plant_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -uroot -p --default-character-setutf8mb4 plant_db plant_database.sql第一行创建名为 plant_db 的数据库指定 utf8mb4 字符集这样中文才存得完整。第二行把 SQL 内容导入指定库--default-character-setutf8mb4 是告诉客户端按这个编码解析文件内容。导入成功后可以用 mysql -uroot -p -e USE plant_db; SHOW TABLES; 验证。需要注意的是SQL 文件开头经常自带 DROP TABLE IF EXISTS执行时会把已存在的同名表直接覆盖。你要是导入到正在用的数据库先检查文件里的删表语句别把一个演示库覆盖掉线上表。3.3 从 JSON/CSV 重建表有些版本只提供 CSV 或 JSON。这种情况没法直接“导入”要先建表再灌数据。用 CSV 重建是最常见的import csv import sqlite3 conn sqlite3.connect(plant_database.db) cur conn.cursor() # 建表时先删掉旧表避免重复 cur.execute(DROP TABLE IF EXISTS plant_info) cur.execute( CREATE TABLE plant_info ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, alias TEXT, family TEXT, genus TEXT, category TEXT, usage TEXT, image_path TEXT ) ) with open(plant_data.csv, encodingutf-8-sig, newline) as f: reader csv.DictReader(f) rows [] for r in reader: # 只取需要的字段避免 CSV 里多出来的列影响入库 rows.append(( r[name].strip(), r.get(alias, ).strip(), r[family].strip() if r.get(family) else , r[category].strip() if r.get(category) else )) cur.executemany( INSERT INTO plant_info (name, alias, family, category) VALUES (?, ?, ?, ?), rows ) conn.commit() conn.close() print(f导入完成共 {len(rows)} 行)这里我做了三件事打开 CSV 用 utf-8-sig 编码避免带 BOM 的文件在入库时把不可见字符写进第一个字段用 DictReader 按列名取值顺序错了也不会张冠李戴插入前 strip 去空格防止企业名称字段里夹着换行符。如果你手里的 CSV 用的是“\t”分隔csv.DictReader 时加参数 delimiter\t 即可。JSON 版本逻辑类似区别是取字段用 r[name] 这类键访问。4. 查询与清洗把“植物大全”变成可复用的业务数据数据导进去只是第一步。真正能用在项目里需要把原始数据变成干净、可查询、可导出的数据。这一章按“查询 → 清洗 → 导出”三层来做。4.1 高频查询场景给数据做一次全面体检先跑几条常用查询看看数据里的科属分布和用途标签是否完整。下面的 SQL 在 SQLite 和 MySQL 里都能跑-- 按科统计植物数量看数据覆盖范围 SELECT family, COUNT(*) AS cnt FROM plant_info GROUP BY family ORDER BY cnt DESC LIMIT 20; -- 查某科下的具体植物 SELECT name, genus, category FROM plant_info WHERE family 银杏科; -- 用途标签检索模糊匹配 SELECT name, usage FROM plant_info WHERE usage LIKE %药用%; -- 找缺图片路径的记录评估能不能做图库展示 SELECT COUNT(*) AS missing_image FROM plant_info WHERE image_path IS NULL OR image_path ;GROUP BY 按科分组统计数量是判断数据分布是否均匀最直接的办法。LIKE %药用% 做模糊匹配适合用途字段里混着多个标签的记录。统计 image_path 缺失数量是为了早发现“这个数据集可能根本没有图片文件”的问题。跑完这几条你对整份数据的完整度就有数了。4.2 清洗脏数据重名、缺失、编码错乱一起处理清洗时最常见的三类问题同一植物重复入库、别名和科属缺失、中文乱码。处理顺序有讲究先清理重复再补空值否则补出来的重复记录还要再删一次。import sqlite3 conn sqlite3.connect(plant_database.db) cur conn.cursor() # 1) 按 name 去重保留 id 最小的那一条 cur.execute( DELETE FROM plant_info WHERE id NOT IN ( SELECT MIN(id) FROM plant_info GROUP BY name ) ) # 2) 补全缺席的 category用“未知”占位 cur.execute(UPDATE plant_info SET category 未知 WHERE category IS NULL OR category ) # 3) 预览乱码记录 cur.execute(SELECT id, name FROM plant_info WHERE name LIKE %% LIMIT 10) for row in cur.fetchall(): print(疑似乱码:, row) conn.commit() conn.close()去重的逻辑是按 name 分组每组保留最小编号其余删除。这个方案在原始数据有几万条时效率不错但如果你打算保留多个同名的不同品种就不能用这个办法。补 category 的 UPDATE 语句是把空值统一成“未知”后面做统计时不会因为空值报错。最后一步用 LIKE %% 查乱码可以在小规模范围内先确认问题记录数量。如果乱码很普遍多半是原始文件编码不是 UTF-8用 iconv 转一次而不是在数据库里逐条改。iconv -f GBK -t UTF-8 plant_data.csv plant_data_utf8.csv这个命令把 GBK 编码的 CSV 转成 UTF-8。注意前提是原文件确实是 GBK,如果原文件是其他编码转换后乱码更严重。拿不准时用 file plant_data.csv 先看编码。4.3 导出训练用的类别清单与划分文件做完清洗数据可以用于训练分类或检测模型。很多人拿到植物数据集第一步就想跑 YOLOv5 训练自己的数据集但你至少要先有类别清单和训练验证划分文件。从数据库导出是效率最高的方式import sqlite3 import random conn sqlite3.connect(plant_database.db) cur conn.cursor() # 导出所有类别名写进 classes.txt cur.execute(SELECT DISTINCT name FROM plant_info ORDER BY name) names [row[0] for row in cur.fetchall()] with open(classes.txt, w, encodingutf-8) as f: f.write(\n.join(names)) # 按 8:2 随机划分训练验证集 cur.execute(SELECT id, name, image_path FROM plant_info WHERE image_path IS NOT NULL AND image_path ! ) records cur.fetchall() random.shuffle(records) split_point int(len(records) * 0.8) train_set records[:split_point] val_set records[split_point:] print(f训练样本 {len(train_set)}验证样本 {len(val_set)}) print(f类别数 {len(names)}) conn.close()DISTINCT 保证类别名称不重复写出的 classes.txt 顺序固定这一点对训练特别重要——YOLO 系列训练时类别编号按文本顺序排序一旦顺序乱标签和框就对应不上。随机打乱后用 8:2 划分是最简单的切分方式。如果你手里的数据本身带图片路径这里导出的就是后续生成标注文件的素材清单。类别名称里不要带空格和括号训练框架解析起来会出问题清洗时顺手替换成下划线。5. 避坑手册导入失败、编码乱码与字段丢失去哪里查这份数据我在不同版本上踩过不少坑。按“现象 → 原因 → 解决”的方式整理五条基本都是拿到文件后最先撞上的问题。5.1 SQL 导入报错 Unknown collation: utf8mb4_0900_ai_ci现象往 MySQL 导入 .sql 文件时报错提示 unknown collation导入中断。原因文件的建表语句用了 MySQL 8.0 默认字符集排序规则 utf8mb4_0900_ai_ci而本机是 MySQL 5.7 或 MariaDB不认识这个规则。解决导入前把文件里的 utf8mb4_0900_ai_ci 全部替换成 utf8mb4_general_ci。用编辑器或 sed 批量替换后重新导入。如果是命令行可以直接执行 sed -i s/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g plant_database.sql。这个坑遇到概率极高因为数据发布者多半是在新版本 MySQL 上导出的。5.2 Excel 打开 CSV 中文全变乱码现象CSV 文件用 Excel 双击打开中文全部变成“锟斤拷”或“”。原因CSV 是 UTF-8 编码但没有带 BOMExcel 默认按 GBK 解析中文就错乱。文件本身没损坏。解决用记事本或 VSCode 打开后另存为 UTF-8 with BOM 格式或者在代码里读文件时用 encodingutf-8-sig。如果你用 pandas 读写成 pd.read_csv(plant_data.csv, encodingutf-8-sig)最省事。这个和我在 3.3 写导入代码时用 utf-8-sig 是同一个原因。5.3 JSON 嵌套字段解析后取不到值现象用 Python 读取 JSON 数据库文件打印顶层键能看到数据但取某条植物详情时拿到的是 None或者对象里再嵌套一层取不到别名和用途。原因发布者在生成 JSON 时用了不同深度的嵌套结构有的记录直接在根节点有的包在 data 或 list 对象里层级不一致。解决先打印一层 JSON 结构再写解析逻辑。常见做法是把根节点数据统一展开import json with open(plant_data.json, encodingutf-8) as f: data json.load(f) # 兼容两种常见结构直接是数组或者包在 data 键下 if isinstance(data, dict) and data in data: records data[data] else: records data print(type(records), len(records))isinstance 判断是为了兼容不同发布版本先确认 records 是列表再遍历取字段。遇到嵌套不一致不要写复杂递归先用这种浅层兼容逻辑把数据拍平。5.4 image_path 字段有值但前端图片全裂现象数据库里 image_path 有路径比如 /images/ginkgo.jpg但网页或小程序里图片 404。原因路径是发布者本地的绝对路径或相对路径到你这边没有对应的图片文件。字段有值不代表图片一定存在。解决先统计该字段有多少非空记录再去对应目录确认文件是否真实存在。如果只有路径没有文件这个字段只能当占位符。做植物识别课程设计时放弃原图直接用网络爬图按 name 重新建目录是更现实的做法。5.5 SQL 文件太大命令行导入到一半就断现象执行 mysql plant_database.sql 后报错 “Lost connection to MySQL server during query” 或超时。原因默认的 max_allowed_packet 偏小SQL 里某条 INSERT 语句过大或者网络连接有中断。批量插数据的 SQL 文件很常见。解决导入前在 MySQL 客户端里临时调大限制SET GLOBAL max_allowed_packet 1073741824; SET GLOBAL net_read_timeout 300; SET GLOBAL net_write_timeout 300;然后重新执行导入命令。这是临时生效重启 MySQL 后恢复默认。遇到超大 SQL 文件还可以用 mysqldump 的分库分表方式分批次导入避免一条事务过大。数据库同步工具做迁移时也会遇到类似问题本质都是单包体积超限。6. 进阶给“植物大全”补图片与训练标注数据本身是结构化字段想用到识别训练还需要把 name 转成类别编号再把图片路径整理成 YOLO 能识别的目录结构。无论你接下来做的是 YOLOv5 训练自己的数据集还是类似鸟类识别系统的设计与实现这类课程项目流程都一样从数据表里导出类别清单把图片按类别归好目录再生成 data.yaml。6.1 从数据表到 data.yaml训练配置怎么生成YOLO 系列要找的 data.yaml 核心就三块训练验证路径、类别数、类别名。类别名必须和 classes.txt 顺序一致不能手填。我用下面这段脚本从数据库直接生成import sqlite3 import yaml conn sqlite3.connect(plant_database.db) cur conn.cursor() cur.execute(SELECT DISTINCT name FROM plant_info ORDER BY name) names [row[0] for row in cur.fetchall()] config { path: ./plant_dataset, train: images/train, val: images/val, nc: len(names), names: names } with open(data.yaml, w, encodingutf-8) as f: yaml.dump(config, f, allow_unicodeTrue, default_flow_styleFalse)生成后打开确认 nc 和 names 数量对得上。这里最容易被忽略的问题是 names 里有中文中文类别名在训练框架里解析没问题但可视化容易乱码。如果你担心这个可以在导出时做一次拼音或英文映射保证目录干净。6.2 先跑通最小样本类别不乱、标注不偏拿到数据后别急着全量训练。我第一次做植物识别的时候直接把整份数据丢进去训练到一半才发现类别顺序和标签顺序错位原因是 classes.txt 里出现过重复 name。从那以后我每次拿到数据集都会强制先走一遍最小流程挑三五个类别每个类别找三张图配好标注跑一次完整训练和验证确认类别顺序、标签编号、路径格式全对再放量跑全量数据。这一步能省掉后面排查标签错乱的大量时间。如果这份数据里 image_path 字段本身就是空的那就要先解决图片来源问题否则后面的训练根本无从谈起。希望帮到你。本文还有配套的精品资源点击获取
返回列表