CSV(逗号分隔值)是一种常见的表格文本格式,因其结构简单、体积小,常用于报表、日志和数据传输。但在现代开发中,Web 应用、接口(API)和 NoSQL 数据库更倾向于使用 JSON。相比 CSV,JSON 支持嵌套结构,表达能力更强,并且与 JavaScript 天然兼容,能更方便地在前端和服务端之间交换数据。
因此,将 CSV 转换为 JSON 已成为数据处理和系统集成中的常见需求。本文将介绍如何使用 Python 将 CSV 转换为多种 JSON 格式,包括扁平化 JSON、嵌套 JSON、按字段分组的 JSON,以及 JSON Lines(NDJSON)。
目录
- 为什么要将 CSV 转换为 JSON
- Python CSV 转 JSON 转换库安装
- Python 将 CSV 转换为扁平化 JSON
- Python 将 CSV 转换为嵌套 JSON
- Python 将 CSV 转换为按字段分组的 JSON
- Python 将 CSV 转换为 JSON Lines(NDJSON)
- 大型 CSV 文件转 JSON 的处理方法
- CSV 转 JSON 的实用建议
- 总结
- 常见问题解答(FAQs)
为什么要将 CSV 转换为 JSON?
CSV 文件轻量且表格化,但缺乏层次结构。JSON 支持结构化和嵌套数据,非常适合 API 和应用程序使用。将 CSV 转换为 JSON 可以实现:
- API 集成: 大多数 API 更偏好 JSON 格式。
- 灵活的数据结构: JSON 支持嵌套对象。
- Web 开发: JSON 与 JavaScript 原生兼容。
- 数据库迁移: NoSQL 和云数据库通常要求 JSON。
- 自动化处理: Python 脚本可高效处理 JSON。
Python CSV 转 JSON 转换库安装
本教程使用 Spire.XLS for Python 读取 CSV 文件,并使用 Python 内置的 json 模块进行 JSON 转换。
为什么选择 Spire.XLS?
- 可将 CSV 文件加载到工作簿结构中,方便逐行或逐列访问。
- 高效提取和操作数据。
- 支持 CSV 转多种JSON格式,例如扁平化或嵌套JSON,以及 NDJSON。
- 可导出 CSV 到 Excel 或 PDF 等其他格式。
安装 Spire.XLS
在终端中运行以下pip命令安装Spire.XLS库:
pip install spire.xls
安装完成后,即可将 CSV 数据转换为不同 JSON 格式。
Python 将 CSV 转换为扁平化 JSON
将 CSV 文件转换为扁平化 JSON 时,每一行 CSV 会生成一个对应的 JSON 对象,所有行被组合到一个 JSON 数组中,并使用首行数据作为键,这样数据结构清晰、便于后续处理
将 CSV 转换为扁平化 JSON 的步骤
- 使用 Workbook.LoadFromFile 将 CSV 文件加载到工作簿中。
- 选择要操作的工作表。
- 从首行提取列名作为 JSON 的键。
- 遍历后续每一行,将每列的值映射到对应的键。
- 将每行生成的字典添加到列表中。
- 使用 json.dump 将列表写入 JSON 文件。
代码示例
from spire.xls import *
import json
# 创建 Workbook 实例并加载 CSV 文件(逗号分隔)
workbook = Workbook()
workbook.LoadFromFile("雇员.csv", ",")
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 提取首行作为 JSON 的键
headers = [sheet.Range[1, j].Text for j in range(1, sheet.LastColumn + 1)]
# 将 CSV 剩余行映射为 JSON 对象
data = []
for i in range(2, sheet.LastRow + 1):
row = {headers[j - 1]: sheet.Range[i, j].Text for j in range(1, sheet.LastColumn + 1)}
data.append(row)
# 写入 JSON 文件
with open("output_flat.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
# 释放工作簿资源
workbook.Dispose()
输出 JSON
Python 将 CSV 转换为嵌套 JSON
当 CSV 中的一行包含相关的列时,可以将这些列组合成嵌套的 JSON 对象。例如,街道和城市两列可以合并为一个地址对象。每一行 CSV 会转换成一个 JSON 对象,并可能包含一个或多个嵌套的子对象。这种方式特别适用于需要将层级数据组织到单条记录中的场景,例如 API 响应或应用配置
将 CSV 转换为嵌套 JSON 的步骤
- 加载 CSV 文件并选择工作表。
- 确定哪些列需要组成嵌套对象(如 街道 和 城市)。
- 遍历每一行,构建包含嵌套字段的 JSON 对象。
- 将每个嵌套对象添加到列表中。
- 使用 json.dump 将列表写入 JSON 文件。
代码示例
from spire.xls import *
import json
# 创建工作簿实例并加载 CSV 文件(使用逗号作为分隔符)
workbook = Workbook()
workbook.LoadFromFile("数据.csv", ",")
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 用于存储转换后的 JSON 数据的列表
data = []
# 从第二行开始循环(假设第一行是表头)
for i in range(2, sheet.LastRow + 1):
# 将每行映射为 JSON 对象,并包含嵌套的 "地址" 对象
row = {
"编号": sheet.Range[i, 1].Text, # 第 1 列: 编号
"姓名": sheet.Range[i, 2].Text, # 第 2 列: 姓名
"地址": { # 地址嵌套对象
"街道": sheet.Range[i, 3].Text, # 第 3 列: 街道
"城市": sheet.Range[i, 4].Text # 第 4 列: 城市
}
}
# 将 JSON 对象添加到列表中
data.append(row)
# 将 JSON 数据写入文件,并设置缩进以便阅读
with open("output_nested.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
# 释放工作簿资源
workbook.Dispose()
输出嵌套 JSON
Python 将 CSV 转换为按字段分组的 JSON
当 CSV 中的多行数据属于同一个父实体时,可以将这些行合并到一个父对象下。例如,在处理订单时,一个订单可能包含多件商品,可以将同一订单的所有商品放入该订单对象的“商品”数组中。每个订单都有唯一标识(如订单编号),其对应的子行会归属于该订单。这种方法适合处理电子商务订单或任何需要将多行相关数据组合成一个整体的场景。
将 CSV 转换为按字段分组 JSON 的步骤
- 加载 CSV 文件并选择工作表。
- 使用 defaultdict 按父键(如 订单编号)对行进行分组。
- 遍历每行,将子项添加到对应父对象的 “商品” 数组中。
- 将分组字典转换为对象列表。
- 写入 JSON 文件。
代码示例
from collections import defaultdict
from spire.xls import *
import json
# 创建工作簿实例并加载 CSV 文件(逗号分隔)
workbook = Workbook()
workbook.LoadFromFile("订单.csv", ",")
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 使用 defaultdict 存储分组数据
# 每个订单编号对应一个字典,包含客户名和商品
data = defaultdict(lambda: {"客户": "", "商品": []})
# 从第二行开始循环(跳过表头)
for i in range(2, sheet.LastRow + 1):
order_id = sheet.Range[i, 1].Text # 第 1 列: 订单编号
customer = sheet.Range[i, 2].Text # 第 2 列: 客户
item = sheet.Range[i, 3].Text # 第 3 列: 商品
# 分配客户名(同一订单编号的所有行相同)
data[order_id]["客户"] = customer
# 将商品添加到订单的商品中
data[order_id]["商品"].append(item)
# 将分组字典转换为对象列表
# 每个对象包含订单编号、客户和商品
result = [{"订单编号": oid, **details} for oid, details in data.items()]
# 将分组数据写入 JSON 文件,并设置缩进便于阅读
with open("output_grouped.json", "w", encoding="utf-8") as f:
json.dump(result, f, indent=4, ensure_ascii=False)
# 释放工作簿资源
workbook.Dispose()
输出按字段分组 JSON
Python 将 CSV 转换为 JSON Lines(NDJSON)
与普通 JSON 数组不同,JSON Lines(也叫 NDJSON,即 Newline Delimited JSON)将每个 JSON 对象单独写在一行,既方便流式处理,又能兼容大数据工具。
为什么使用 NDJSON?
- **支持流式处理:**可逐条处理数据记录,无需一次性将整个文件加载到内存中,适合大数据场景。
- **大数据工具兼容:**Elasticsearch、Logstash、Hadoop 等系统都能原生处理 NDJSON。
- **增强容错性:**即使某行数据损坏,其余行仍可正常使用,不影响整体文件。
将 CSV 转换为 NDJSON 的步骤
- 加载 CSV 文件并选择工作表。
- 提取首行作为 JSON 的键。
- 遍历每行,将其映射为 JSON 对象,并逐行写入NDJSON文件,每行一个 JSON 对象。
代码示例
from spire.xls import *
import json
# 创建 Workbook 实例并加载 CSV 文件(逗号分隔)
workbook = Workbook()
workbook.LoadFromFile("雇员.csv", ",")
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 提取首行作为 JSON 的键
headers = [sheet.Range[1, j].Text for j in range(1, sheet.LastColumn + 1)]
# 打开文件以写入 NDJSON
with open("output.ndjson", "w", encoding="utf-8") as f:
# 从第二行开始遍历每行数据
for i in range(2, sheet.LastRow + 1):
# 将每列数据映射为 JSON 对象
row = {headers[j - 1]: sheet.Range[i, j].Text for j in range(1, sheet.LastColumn + 1)}
# 写入文件,每行一个 JSON 对象
f.write(json.dumps(row, ensure_ascii=False) + "\n")
# 释放工作簿资源
workbook.Dispose()
输出 NDJSON
大型 CSV 文件转 JSON 处理方法
对于比较大的 CSV 文件,一次性将所有数据加载到内存中可能效率不高,甚至会导致内存不足。使用 Spire.XLS,你仍然可以将 CSV 文件加载为工作表,但不必将所有行一次性添加到列表中,而是可以分批处理并逐步写入 JSON 文件。这种方法可以有效减少内存占用,非常适合在 Python 中进行大型 CSV 到 JSON 的转换。
代码示例
from spire.xls import *
import json
# 创建 Workbook 实例并加载 CSV 文件(逗号分隔)
workbook = Workbook()
workbook.LoadFromFile("测试.csv", ",")
# 获取第一个工作表
sheet = workbook.Worksheets[0]
# 打开 JSON 文件用于写入
with open("output_large.json", "w", encoding="utf-8") as json_file:
json_file.write("[\n") # 开始 JSON 数组
first = True # 用于处理对象之间的逗号
# 从第二行开始遍历每行数据(跳过表头)
for i in range(2, sheet.LastRow + 1):
# 将每列数据映射到表头,生成字典
row = {sheet.Range[1, j].Text: sheet.Range[i, j].Text
for j in range(1, sheet.LastColumn + 1)}
# 如果不是第一行,在前面添加逗号
if not first:
json_file.write(",\n")
# 写入 JSON 对象
json.dump(row, json_file, ensure_ascii=False)
first = False
json_file.write("\n]") # 结束 JSON 数组
# 释放工作簿资源
workbook.Dispose()
CSV 转 JSON 的实用建议
在 Python 中将 CSV 转换为 JSON 时,遵循以下实用建议可以确保数据的完整性和兼容性:
- 始终使用 CSV 表头作为 JSON 键:确保每列数据都有明确的键名,便于后续访问和处理。
- 处理缺失值:对空值使用 null 或预设的默认值,避免数据不完整。
- 统一数据类型:将数字字符串转换为整数或浮点数,以保持数据类型一致。
- 使用 UTF-8 编码保存 JSON 文件:保证中文和特殊字符正确显示。
- 大文件逐行处理:针对大 CSV 文件,采用逐行或分批写入 JSON 的方式,减少内存占用。
- 写入后验证 JSON 结构:尤其是嵌套 JSON,要确保格式正确,避免解析错误。
总结
在 Python 中将 CSV 转换为 JSON,可以让数据处理更加高效,并方便用于现代应用程序。借助 Python 及像 Spire.XLS for Python 这样的库,你可以:
- 将扁平的 CSV 文件转换为结构化的 JSON 对象;
- 将相关的 CSV 数据组织成嵌套的 JSON 结构;
- 将多行 CSV 数据按逻辑分组,生成便于分析或 API 使用的 JSON 对象;
- 为大数据集或流式处理场景创建 JSON Lines(NDJSON)格式;
- 高效处理大型 CSV文件,而无需一次性加载所有数据到内存中。
通过这些方法,你可以高效地将 CSV 数据转换为多种 JSON 格式,并应用到 API 开发、系统集成、大数据处理等实际场景中。
常见问题解答(FAQs)
Q1:如何在 Python 中将带表头的 CSV 转换为 JSON?
A1: 如果 CSV 文件有表头,可使用首行作为键,将后续行映射为字典。使用 Spire.XLS 时,可通过 sheet.Range[1, j].Text 获取表头内容。
Q2:如何在 Python 中将 CSV 转换为嵌套 JSON?
A2: 找出相关列(例如 街道 和 城市),在构建 JSON 时将它们组合成子对象。参考上文的嵌套 JSON 示例。
Q3:处理大文件 CSV 转 JSON 的最佳方法是什么?
A3: 使用流式处理方式,即逐行处理并立即写入 JSON,而不是一次性将所有数据加载到内存中。
Q4:Spire.XLS 能处理自定义分隔符的 CSV 文件吗?
A4: 可以。在 LoadFromFile 方法中指定分隔符,例如 "," 或 ";"。
Q5:如何将 JSON 再转换回 CSV?
A5: 使用 Python 的 json 模块将 JSON 文件读取为字典列表,然后用 Spire.XLS for Python 写回 CSV。
Q6:如何在 Python 中将 CSV 转为 JSON Lines(NDJSON)?
A6: JSON Lines(NDJSON)格式会将每个 JSON 对象写在单独的一行。可逐行将 CSV 数据写入输出文件,这样内存占用低,并且兼容 Elasticsearch、Logstash 等大数据处理工具。