JSON 和 JSONL 的区别
1. JSON 格式
-
全称: JavaScript Object Notation
-
结构: JSON 是一种树状嵌套结构,整个文件是一个完整的 JSON 对象。
-
特点:
- 文件中通常只有一个 JSON 对象。
- 数据可以嵌套,例如对象中包含数组,数组中包含对象。
- 适用于需要表示复杂数据关系的场景。
-
示例:
[
{
"id": 1,
"name": "Alice",
"age": 25
},
{
"id": 2,
"name": "Bob",
"age": 30
}
]
2. JSONL 格式
-
全称: JSON Lines
-
结构: JSONL 是一个轻量化的格式,每行表示一个独立的 JSON 对象。
-
特点:
- 数据是逐行存储的,每行是一个完整的 JSON 对象。
- 文件中的每行可以独立解析,彼此没有嵌套关系。
- 适用于需要流式处理或者分布式处理的场景(如日志处理、数据批量加载)。
-
示例:
{"id": 1, "name": "Alice", "age": 25}
{"id": 2, "name": "Bob", "age": 30}
主要区别
特性 | JSON | JSONL |
---|---|---|
存储方式 | 整体是一个完整的 JSON 对象 | 每行是一个 JSON 对象 |
读取方式 | 一次性读取整个文件 | 可以逐行读取和解析 |
嵌套支持 | 可以嵌套复杂结构 | 每行独立,通常不嵌套 |
处理场景 | 适合一次性加载的应用 | 适合流式、分布式处理场景 |
文件大小影响 | 文件越大,加载越慢 | 可以按行加载,处理更高效 |
使用场景
-
JSON:
- 配置文件
- 小规模数据存储
- 描述复杂结构的层次化数据
-
JSONL:
- 大规模数据处理
- 日志文件存储
- 数据流应用(例如机器学习训练数据)
选择建议
- 文件较小:优先使用 JSON,便于读取和管理。
- 文件较大:优先使用 JSONL,可以逐行加载,避免内存占用过高。
- 日志处理/分布式处理:使用 JSONL,每行可以独立处理,适合流式计算。
如果有具体的数据需求或处理场景,可以告诉我,我可以给出更针对性的建议!
加载文件方式
1. with open 加载
# 加载 JSON 文件
with open(data_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# 加载 JSONL 文件
with open(data_path, 'r', encoding='utf-8') as f:
data = [json.loads(line.strip()) for line in f]
2. Hugging Face datasets
库加载
from datasets import load_dataset
# 加载 JSON 数据
dataset = load_dataset("json", data_files="path_to_your_file.json")
# 加载 JSONL 数据
dataset = load_dataset("json", data_files="path_to_your_file.jsonl")
# 加载多个 JSON 文件
data_files = {
"train": "path_to_train.json",
"test": "path_to_test.json",
}
dataset = load_dataset("json", data_files=data_files)
# dataset的其他用法
dataset = dataset.select(range(5))
# 训练集和验证集比例划分
train_ratio = 0.9
split_dataset = dataset.train_test_split(test_size = 1 - train_ratio)
train_dataset = split_dataset["train"]
eval_dataset = split_dataset["test"]
# 数据预处理函数: 将每个数据转化为 input_ids、labels、attention_mask
def tokenize_function(examples):
return tokenizer(
# examples["input"] + examples["output"],
examples["input"]
padding="max_length",
truncation=True,
max_length=max_seq_length,
)
# tokenizer分词获取 input_ids、labels、attention_mask
train_dataset = train_dataset.map(tokenize_function, batched=True, remove_columns=["input", "output"])
eval_dataset = eval_dataset.map(tokenize_function, batched=True, remove_columns=["input", "output])
# 省略中间代码 ………………
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
data_collator=data_collator,
)
输出如下:
Generating train split: 3 examples [00:00, 429.49 examples/s]
DatasetDict({
train: Dataset({
features: ['input', 'output'],
num_rows: 3
})
})