CSV 校验与数据质量分析
数据互转
正在载入
正在加载工具
正在准备工具,暂时无法估算剩余时间。
本工具的全部运算都发生在你的浏览器中,输入内容不会发送到任何服务器。
关于这个工具
清洗、连接或导入 CSV/TSV 前,先了解数据实际包含什么。此工具在本地检查引号、表头和行宽,按列统计缺失状态、精确不同值及重复情况。需要时再选择组合键、数值列或严格日期格式。原始字符串始终不变,包括前导零标识符和长整数。计数与行位置帮助定位问题;工具不生成任意的综合质量分,也不证明业务数据正确。默认不显示单元格示例值,分析在可取消的浏览器工作线程中运行。
常见用途
- 检查客户导出中的缺少尾部字段、空字符串、纯空白和明确配置的 N/A 标记,保留这些状态之间的差异。
- 比较快照或连接表格前,查找整行重复,或 order_id + line_id 组合键重复;查看重复组与多余行数量,不删除数据。
- 先查看列的推测类型,再为明确的度量列启用数值统计,为已知日期列启用严格日历检查,以便制定清洗规则。
使用方法
- 1.粘贴分隔文本,或选择 UTF-8、UTF-16 LE、UTF-16 BE 编码的文件。明确指定逗号、制表符、分号或竖线,以及首条记录是否为表头。先核对设置再解读结果;引号内换行属于同一条 CSV 记录,不是新数据行。 按需配置来源中使用的精确空值标记字符串。匹配区分大小写且针对整个单元格,不自动去空白、转换大小写或生成 null 值。如需检查组合键重复,按位置选择键列;重复或空白表头不会让位置选择产生歧义。
- 2.仅为表示数量的列开启数值统计。选择来源使用的明确日期格式,该格式影响所有列的日期推测。若知道预期约束,可为指定列添加必填、唯一或类型规则;日期列使用日期类型规则。只有确实需要在预览和报告中显示原始文本时才开启示例值;默认报告保留计数、位置、表头和设置,不含示例单元格。
- 3.运行分析,检查结构问题、逐列计数、推测类型冲突、整行重复与选定键重复。提示是供复核的线索,不是自动修改指令。先修复错误引号才能获得完整分析。修改输入或设置会使旧结果失效,请重新运行。 确认隐私设置后下载 JSON 或 CSV 质量报告。建议保持 CSV 公式防护开启;原始 CSV 是带警告的主动选项。JSON 将包含的字符串作为数据保存。导出内容是分析结论,不是清洗后的源表。需要修复时使用 CSV 查看与清洗工具,再返回复查。取消可停止当前任务;清空可移除工具内的当前输入与结果。
可复现的 CSV 质量检查
区分四种缺失状态
{
"input": "id,value\n1\n2,\n3, \n4,N/A\n5,null\n6,n/a\n7,N/A",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [
"N/A"
],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 7,
"columns": 2,
"cells": 13,
"missing": 1,
"empty": 1,
"whitespace": 1,
"nullMarker": 2,
"raggedRows": 1
},
"columns": [
{
"index": 0
},
{
"index": 1,
"present": 6,
"unique": 5,
"duplicateValues": 1,
"missing": 1,
"empty": 1,
"whitespace": 1,
"nullMarker": 2
}
]
}第二列包含一个缺少字段、一个已存在的空字符串、一个纯空白值,以及两个精确匹配的 N/A 标记。小写 n/a 和字面 null 仍是普通文本。六个已存在字符串都参与精确不同值统计,包括空字符串、空白和标记,其中五个不同。以下示例仅列出相关报告字段,不是完整报告。
区分相同行与重复 ID
{
"input": "id,value\nA,x\nA,x\nA,y\nB,\nB\nC,",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [
0
],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 6,
"missing": 1,
"empty": 2
},
"duplicates": {
"records": {
"groups": 1,
"duplicateRows": 1,
"participatingRows": 2,
"examples": [
{
"row": 2,
"previousRow": 1
}
]
},
"keys": {
"groups": 2,
"duplicateRows": 3,
"participatingRows": 5,
"examples": [
{
"row": 2,
"previousRow": 1
},
{
"row": 3,
"previousRow": 1
},
{
"row": 5,
"previousRow": 4
}
]
}
}
}第 1、2 行完全相同;第 3 行也使用 A 键,但值不同。两个 B 行的键相同,不过空字符串与缺少字段使整行不同。两个重复键组涉及五行,相对各组首行共多出三行。工具不删除任何行。
组合键不会因简单拼接而误撞
{
"input": "region,id\nnorth,001\nnorth,1\nsouth,001\nnorth,001\nnorth\nnorth,\na|b,c\na,b|c",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [
0,
1
],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 8,
"missing": 1,
"empty": 1
},
"duplicates": {
"keys": {
"groups": 1,
"duplicateRows": 1,
"participatingRows": 2,
"examples": [
{
"row": 4,
"previousRow": 1
}
]
}
}
}只有第 4 行重复第 1 行完整的 north + 001 键。001 与 1 不同,缺少 id 与空 id 也不同。[a|b, c] 和 [a, b|c] 是不同元组,即使简单用竖线拼接会混淆。请求中的列索引从 0 开始,诊断数据行号从 1 开始。
保留前导零与相邻的长 ID
{
"input": "code\n001\n1\n9007199254740992\n9007199254740993\n001",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [
0
],
"dateFormat": "YYYY-MM-DD",
"constraints": [
{
"column": 0,
"required": false,
"unique": true,
"type": "any"
}
],
"includeExamples": false
}
}{
"columns": [
{
"index": 0,
"present": 5,
"unique": 4,
"duplicateValues": 1,
"types": {
"number": 1,
"date": 0,
"boolean": 0,
"identifier": 4,
"text": 0
},
"inferred": "mixed",
"conflicts": 1,
"numeric": {
"accepted": 1,
"excluded": 4,
"min": "1",
"max": "1",
"sum": "1",
"mean": 1,
"meanApproximate": true
}
}
],
"summary": {
"constraintViolations": 1
},
"duplicates": {
"records": {
"groups": 1,
"duplicateRows": 1,
"participatingRows": 2
}
}
}两个长 ID 保持不同字符串,001 不会变成 1。只有规范数量文本 1 纳入数值统计。此列为混合类型,四个单元格呈标识符形式,一个呈数值形式。显式唯一性规则只标记第二个 001,不会误把两个长 ID 合并。
统计被排除值并保持十进制合计精确
{
"input": "amount\n0.1\n0.2\n0.3\n001\n9007199254740992\n1e3\n+2\n 2 \nInfinity\n0.1234567\n\"\"",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [
0
],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 11,
"empty": 1
},
"columns": [
{
"index": 0,
"numeric": {
"accepted": 3,
"excluded": 7,
"min": "0.1",
"max": "0.3",
"sum": "0.6",
"mean": 0.19999999999999998,
"meanApproximate": true
}
}
]
}仅 0.1、0.2、0.3 被采纳,精确十进制合计为字符串 0.6。七个有内容的值因标识符、指数/加号/外部空格形式、非有限文本或超过六位小数而被排除。空单元格属于缺失状态,不计数值排除。平均值明确为近似值,末位浮点误差不会改变精确合计。
区分不存在的日期与更广的日期规则
{
"input": "date\n29/02/2024\n29/02/2023\n31/04/2024\n01/02/2024\n\"\"\n1/2/2024\nN/A",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [
"N/A"
],
"keys": [],
"numericColumns": [],
"dateFormat": "DD/MM/YYYY",
"constraints": [
{
"column": 0,
"required": false,
"unique": false,
"type": "date"
}
],
"includeExamples": false
}
}{
"summary": {
"rows": 7,
"empty": 1,
"nullMarker": 1,
"invalidDates": 2,
"constraintViolations": 3
},
"columns": [
{
"index": 0,
"types": {
"number": 0,
"date": 2,
"boolean": 0,
"identifier": 0,
"text": 3
},
"invalidDates": 2
}
]
}2024 年闰日和 2 月 1 日符合 DD/MM/YYYY。2023 年闰日与 4 月 31 日虽符合所选外形,却不符合日历,因此无效日期计数为二。日期类型规则还拒绝未补零的 1/2/2024,共三条规则违规。此规则不是必填,故空字符串和已配置的 N/A 跳过类型检查。
明确选择月在前的含义
{
"input": "date\n01/02/2024\n12/31/2024\n31/12/2024",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "MM/DD/YYYY",
"constraints": [
{
"column": 0,
"required": false,
"unique": false,
"type": "date"
}
],
"includeExamples": false
}
}{
"summary": {
"invalidDates": 1,
"constraintViolations": 1
},
"columns": [
{
"index": 0,
"types": {
"number": 0,
"date": 2,
"boolean": 0,
"identifier": 0,
"text": 1
},
"inferred": "mixed"
}
]
}MM/DD/YYYY 将 01/02/2024 解释为 1 月 2 日,并接受 12/31/2024。31/12/2024 因不存在第 31 月而无效。若选择 DD/MM/YYYY,首个字符串的含义就不同。报告仅分类,不改写日期字符串。
明确应用必填、唯一与类型规则
{
"input": "id,amount,flag\nA,10,true\nA,x,TRUE\n,20,false\nB,,false\nC,30,yes",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [
{
"column": 0,
"required": true,
"unique": true,
"type": "any"
},
{
"column": 1,
"required": true,
"unique": false,
"type": "number"
},
{
"column": 2,
"required": false,
"unique": false,
"type": "boolean"
}
],
"includeExamples": false
}
}{
"summary": {
"rows": 5,
"empty": 2,
"constraintViolations": 6,
"typeConflicts": 3
},
"columns": [
{
"index": 0,
"inferred": "text"
},
{
"index": 1,
"inferred": "mixed",
"conflicts": 1
},
{
"index": 2,
"inferred": "mixed",
"conflicts": 2
}
]
}六条显式规则违规分别是重复 A、缺失 id、非数值 x、缺失 amount,以及不是布尔值的 TRUE 和 yes。只有小写 true、false 算布尔值。三条启发式类型冲突与六条规则违规分别统计,不能相加当作互不重叠的问题单元格数。
诊断表头但不改写名称
{
"input": ", id ,id\nA,B\nC,D,E,F",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 2,
"columns": 4,
"expectedColumns": 3,
"cells": 6,
"raggedRows": 2,
"headerIssues": 2,
"missing": 2,
"structuralValid": false
},
"columns": [
{
"index": 0,
"name": ""
},
{
"index": 1,
"name": " id "
},
{
"index": 2,
"name": "id"
},
{
"index": 3,
"name": "column4"
}
],
"issues": [
{
"code": "emptyHeader",
"row": 0,
"column": 1
},
{
"code": "duplicateHeader",
"row": 0,
"column": 3,
"expected": 2
},
{
"code": "ragged",
"row": 1,
"expected": 3,
"actual": 2
},
{
"code": "ragged",
"row": 2,
"expected": 3,
"actual": 4
}
]
}第一个空白表头被标记。表头重复诊断比较去除前后空白的名称,因此 id 与前面的带空格名称重复,但显示名称保持不变。表头期望三列,两列和四列记录都算行宽异常。分析包含第四个位置列,因此短的首行有两个缺少单元格。表头诊断使用行号 0。
分析无表头且含多行单元格的 TSV
{
"input": "001\t\"first\nline\"\n002\t\"say \"\"yes\"\"\"\n001\t\"first\nline\"",
"options": {
"delimiter": "\t",
"header": false,
"nullMarkers": [],
"keys": [
0
],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": true
}
}{
"summary": {
"rows": 3,
"columns": 2,
"cells": 6,
"structuralValid": true
},
"columns": [
{
"index": 0,
"name": "column1",
"inferred": "identifier"
},
{
"index": 1,
"name": "column2",
"examples": [
{
"row": 1,
"value": "first\nline",
"truncated": false
},
{
"row": 2,
"value": "say \"yes\"",
"truncated": false
},
{
"row": 3,
"value": "first\nline",
"truncated": false
}
]
}
],
"duplicates": {
"records": {
"groups": 1,
"duplicateRows": 1,
"participatingRows": 2
},
"keys": {
"groups": 1,
"duplicateRows": 1,
"participatingRows": 2
}
}
}明确选择制表符,首条记录作为数据。引号内换行保留在一个字段中,两个双引号解析为一个字面双引号。共有三条数据记录,与物理行数无关。column1、column2 是位置标签;开启示例会有意显示解析后的原始单元格文本。
默认报告不包含单元格示例
{
"input": "id,note\n001,=1+1\n002,<script>alert(1)</script>",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"exact": true,
"examplesIncluded": false,
"columns": [
{
"index": 0,
"examples": []
},
{
"index": 1,
"examples": []
}
],
"issues": []
}默认两个列示例列表都为空。疑似公式和 HTML 的字符串按文本分析,不执行公式或脚本。报告仍包含表头与配置,因此此设置不等于数据匿名化。此分析工具也不以完整原始行作为导出格式。
主动开启有限示例,但不把截短称为脱敏
{
"input": "=header\n=1+1\n<img src=x onerror=alert(1)>\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nlast value",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": true
}
}{
"examplesIncluded": true,
"columns": [
{
"index": 0,
"name": "=header",
"examples": [
{
"row": 1,
"value": "=1+1",
"truncated": false
},
{
"row": 2,
"value": "<img src=x onerror=alert(1)>",
"truncated": false
},
{
"row": 3,
"value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…",
"truncated": true
}
]
}
]
}只显示前三个有内容的示例;第三个字符串截到 80 个 UTF-16 代码单元后加省略号。第四个值不列出,但仍计入统计。界面安全显示文本。受保护 CSV 会给疑似公式的表头和示例加单引号,JSON 保留字符串。截短与公式防护都不会删除私密内容。
错误引号会停止分析
{
"input": "id,note\n1,\"unfinished",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"error": "syntax"
}起始引号没有闭合,因此解析器返回 syntax,不提供质量报告。应修复来源引号,不应将其视为空数据或分析成功。解析器记录坐标包含表头,正常报告的数据行坐标不包含表头。
仅有表头不代表已经观察到数据
{
"input": "id,amount",
"options": {
"delimiter": ",",
"header": true,
"nullMarkers": [],
"keys": [],
"numericColumns": [
1
],
"dateFormat": "YYYY-MM-DD",
"constraints": [],
"includeExamples": false
}
}{
"summary": {
"rows": 0,
"columns": 2,
"cells": 0,
"structuralValid": true
},
"columns": [
{
"index": 0,
"inferred": "none",
"unique": 0
},
{
"index": 1,
"inferred": "none",
"unique": 0,
"numeric": {
"accepted": 0,
"excluded": 0,
"min": null,
"max": null,
"sum": "0",
"mean": null,
"meanApproximate": true
}
}
]
}有效表头不意味着存在数据。两列都没有推测类型或不同值。所选数值列没有可采纳值,最小值、最大值和平均值为 null,合计为字符串 0。这不表示测量值为零,也不保证数据完整。
数据质量复核中的常见误区
- 未核对分隔符或表头设置就接受统计结果。
- 把缺少字段、空字符串、纯空白和字面空值标记混为一谈。
- 多条订单明细合理共用 order_id,却只选择 order_id 作为唯一键。
- 仅因包含数字,就把前导零 ID 或长账号当作数量。
- 把推测类型当成业务规则验证,或以为平均值纳入了所有非空单元格。
- 猜测有歧义的日期格式,或期待自动修复无效日期。
- 开启示例后分享报告,误以为数量有限或截短的值已匿名化。
限制与说明
- 分隔符需明确选择逗号、制表符、分号或竖线,不自动检测。文件支持 UTF-8、UTF-16 LE、UTF-16 BE 及匹配的可选 BOM,支持引号内分隔符、双引号转义和多行单元格。错误引号或无效解码会阻止分析,不返回容易误解的局部统计。空白或重复表头、行宽不一致会产生诊断。表头诊断比较去除前后空白后的名称,但显示名称与单元格值不变。列按数字位置识别,不会悄悄合并重复名称。无表头时生成位置标签。报告数据行号不含表头,表头问题使用行号 0;解析器记录号包含表头,多行单元格可能让它不同于物理行号。
- 缺少尾部字段、已存在的空字符串、纯空白字符串、精确配置的空值标记是不同状态。纯空白判断使用 ECMAScript trim() 的空白集合,但不修改原值。字面文本 null 或 N/A 只有明确配置后才算标记。缺失统计不是必填规则:可选字段为空可能完全合理。不同值及重复检查按解析后的字符串精确比较,因此 001 与 1、A 与 a、空格与空字符串不同。缺少键分量也不同于空分量。组合键保留各个分量,不靠拼接分隔符区分;发现键重复不能判断哪条记录正确。 不同值统计纳入所有已存在的字符串,包括空字符串、空白和标记文本,但不计缺少字段。多余重复值数等于已存在单元格数减不同值数。空字符串与纯空白的分类优先于配置标记,因此四种缺失状态互不重叠。
- 推测类型与冲突是启发式结果,不是权威数据模式或业务校验。出现多种类型时列标记为混合,冲突数为非缺失单元格总数减最大类型组数量。并列时仍为混合;定位冲突按数值、日期、布尔、标识符、文本的顺序打破并列,不代表语义优先级。只有小写 true、false 算布尔值。前导零或至少 16 位数字的整数样式字符串按标识符形式处理。不强制转换、改写或执行值。数值统计需主动开启,合格文本可带负号,整数部分为不带多余前导零的规范数字,可含一至六位小数;有效数字最多 15 位,绝对值不超过 Number.MAX_SAFE_INTEGER。前导加号、指数形式、外部空白、Infinity、NaN 和更高精度均排除。数值排除只计不合格的非缺失字符串。最小值、最大值和合计为精确十进制字符串;平均值明确为近似二进制浮点数,不是精确十进制账务结果。 所选日期格式为 YYYY-MM-DD、DD/MM/YYYY、MM/DD/YYYY 或 YYYY/MM/DD。有效日期须字段宽度精确,且为 0001–9999 年内真实存在的前推公历日期。不猜测地区习惯,不解析时间戳、不转换时区、不自动修复。无效日期计数仅标记外形符合所选格式但不符合日历的非缺失字符串;逐列日期类型规则还会拒绝外形不符的非缺失字符串。这些计数可能重叠,不能当作不同问题单元格相加。必填规则拒绝四种缺失状态;唯一规则精确比较非缺失原字符串,标记首次之后的每次出现。数值、日期、布尔规则检查各自语法;文本规则接受任何非缺失字符串,包括数字样式文本。类型和唯一规则跳过缺失状态,除非同时启用必填。约束均需明确指定,输入始终不变。
- 上限为文件字节与解码后 UTF-8 文本各 2 MiB、10,000 数据行、128 列、200,000 个实际单元格;各列精确不同值集合合计最多 200,000 项。报告上限为 1 MiB。保留前 500 条定位问题,并显示截断标记,完整问题计数仍可查看。每列示例列表最多三项。保留的问题记录也可能各自带示例,因此每列三项不是整体披露上限。示例摘录最多 80 个 UTF-16 代码单元,表头摘录最多 160 个,不拆分代理对;截短时另加省略号。最多配置 100 个标记,每个 200 个代码单元。计数覆盖完整的合格输入,不只统计预览样本。缺少单元格按最宽表格统计,实际单元格数不包含缺少位置。超过分析上限会阻止操作。工作线程、取消与超时可降低负担,但不是严格浏览器内存沙箱;更大文件请使用本地数据工具。
- 默认关闭单元格示例值。开启后,页面与导出可能含有私密数据;数量有限或截短不等于匿名化。即使关闭示例,报告仍包含表头、配置标记、选项、位置和汇总计数,也可能敏感。报告不会将全部原始输入行作为数据表导出。此工具不会上传输入或报告,也不写入浏览器存储。工作数据保留在页面或工作线程内存中,直到清空、替换或关闭页面。下载报告会留在您保存或分享的位置,不再受工具控制。 受保护 CSV 会给疑似公式的来源文本加前导单引号,因此会改变导出的文本。仅使用 CSV 引号不足以防公式注入,防护也不能保证所有表格软件或重新保存后的文件都安全。JSON 将启用的示例作为字符串,不执行其内容,但仍会包含您选择导出的示例。两种报告都不是可直接导入的修复表、数据模式契约、业务规则审计,也不保证数据适合公开。
常见问题
为什么区分缺少字段、空字符串、空白和空值标记?
表头为 id,value 时,只有 7 的记录缺少 value 字段;7, 含有已存在的空字符串;7, 含有空白文本。7,N/A 含有字符串 N/A,只有明确配置后才计为空值标记。这些状态可能指向不同的来源问题,混为一谈会掩盖线索。工具保留原始数据,分别报告。
整行重复和键重复有什么区别?
整行重复要求行长度相同,且每个位置的字符串完全相同。选定键重复只比较所选位置列组成的元组。两行 order_id 相同而 status 不同,属于键重复,但不是整行重复。包含三个成员的组涉及三行,相对首个成员多出两行。工具不删除行,也不选择保留哪一行。
推测类型是否意味着整列都必须符合该类型?
不是。标签概括观察到的语法,混合列可能符合设计。冲突数是最大类型组之外的单元格数,并非外部模式验证。若知道约束,可指定必填、唯一与类型规则。必填涵盖缺少字段、空字符串、纯空白和标记;唯一性跳过这些状态,对剩余原字符串精确比较。数值统计需明确选列;精度规则范围内的最小、最大与合计为精确十进制值,平均值则是近似值。 先检查分隔符、错误引号以及意外表头或行宽,再确认缺失值约定和所选键能否识别唯一记录。仅为明确的列开启日期或数值检查。可在 CSV 查看与清洗工具中应用指定规则,或排查上游导出,然后重新分析。没有任意质量分需要追求;应根据目标系统与业务要求判断哪些问题重要。
可以分享不暴露源单元格值的报告吗?
保持示例值关闭即可。计数和行位置仍可帮助复核,但表头、配置标记、选项和汇总信息仍包含在报告中,可能识别敏感数据集,分享前须检查。开启示例会有意包含数量有限的原始值;截短不是脱敏。本地处理与公式防护也不等于匿名化。