加载
您的数据可以存储在不同位置;它们可以位于本地机器的磁盘上、Github 仓库中以及内存中的数据结构中,例如 Python 字典和 Pandas DataFrame。无论数据集存储在哪里,🤗 Datasets 都可以帮助您加载它。
本指南将向您展示如何从以下位置加载数据集
- Hugging Face Hub
- 本地文件
- 内存中的数据
- 离线
- 拆分的特定切片
- 本地加载脚本(遗留)
有关加载其他数据集模态的更多详细信息,请查看加载音频数据集指南、加载图像数据集指南或加载文本数据集指南.
Hugging Face Hub
数据集从数据集加载脚本加载,该脚本下载并生成数据集。但是,您也可以从 Hub 上的任何数据集存储库中加载数据集,而无需加载脚本!首先 创建数据集存储库 并上传您的数据文件。现在您可以使用 load_dataset() 函数来加载数据集。
例如,尝试通过提供存储库命名空间和数据集名称来加载此 演示存储库 中的文件。此数据集存储库包含 CSV 文件,以下代码从 CSV 文件加载数据集。
>>> from datasets import load_dataset
>>> dataset = load_dataset("lhoestq/demo1")
某些数据集可能基于 Git 标签、分支或提交具有多个版本。使用 revision
参数指定要加载的数据集版本。
>>> dataset = load_dataset(
... "lhoestq/custom_squad",
... revision="main" # tag name, or branch name, or commit hash
... )
有关如何在 Hub 上创建数据集存储库以及如何上传数据文件的更多详细信息,请参阅 将数据集上传到 Hub 教程。
默认情况下,没有加载脚本的数据集将所有数据加载到 train
分区中。使用 data_files
参数将数据文件映射到分区,例如 train
、validation
和 test
。
>>> data_files = {"train": "train.csv", "test": "test.csv"}
>>> dataset = load_dataset("namespace/your_dataset_name", data_files=data_files)
如果您没有指定要使用哪些数据文件,load_dataset() 将返回所有数据文件。如果您加载大型数据集(如 C4,大约 13TB 的数据),这可能需要很长时间。
您还可以使用 data_files
或 data_dir
参数加载文件的特定子集。这些参数可以接受相对于加载数据集的位置的基路径解析的相对路径。
>>> from datasets import load_dataset
# load files that match the grep pattern
>>> c4_subset = load_dataset("allenai/c4", data_files="en/c4-train.0000*-of-01024.json.gz")
# load dataset from the en directory on the Hub
>>> c4_subset = load_dataset("allenai/c4", data_dir="en")
split
参数也可以将数据文件映射到特定分区。
>>> data_files = {"validation": "en/c4-validation.*.json.gz"}
>>> c4_validation = load_dataset("allenai/c4", data_files=data_files, split="validation")
本地和远程文件
数据集可以从存储在您计算机上的本地文件和远程文件加载。数据集最有可能存储为 csv
、json
、txt
或 parquet
文件。 load_dataset() 函数可以加载每种文件类型。
CSV
🤗 Datasets 可以读取由一个或多个 CSV 文件组成的数据集(在这种情况下,将您的 CSV 文件作为列表传递)
>>> from datasets import load_dataset
>>> dataset = load_dataset("csv", data_files="my_file.csv")
有关更多详细信息,请查看 如何从 CSV 文件加载表格数据集 指南。
JSON
JSON 文件使用 load_dataset() 直接加载,如下所示。
>>> from datasets import load_dataset
>>> dataset = load_dataset("json", data_files="my_file.json")
JSON 文件具有多种格式,但我们认为最有效的格式是具有多个 JSON 对象;每一行代表数据的一行。例如:
{"a": 1, "b": 2.0, "c": "foo", "d": false}
{"a": 4, "b": -5.5, "c": null, "d": true}
您可能会遇到的另一种 JSON 格式是嵌套字段,在这种情况下,您需要指定 field
参数,如下所示:
{"version": "0.1.0",
"data": [{"a": 1, "b": 2.0, "c": "foo", "d": false},
{"a": 4, "b": -5.5, "c": null, "d": true}]
}
>>> from datasets import load_dataset
>>> dataset = load_dataset("json", data_files="my_file.json", field="data")
要通过 HTTP 加载远程 JSON 文件,请传递 URL。
>>> base_url = "https://rajpurkar.github.io/SQuAD-explorer/dataset/"
>>> dataset = load_dataset("json", data_files={"train": base_url + "train-v1.1.json", "validation": base_url + "dev-v1.1.json"}, field="data")
虽然这些是最常见的 JSON 格式,但您会看到其他格式不同的数据集。 🤗 Datasets 识别这些其他格式,并将根据 Python JSON 加载方法相应地回退以处理它们。
Parquet
Parquet 文件以列式格式存储,与基于行的文件(如 CSV)不同。大型数据集可能存储在 Parquet 文件中,因为它在返回查询方面更高效且更快。
要加载 Parquet 文件,请执行以下操作:
>>> from datasets import load_dataset
>>> dataset = load_dataset("parquet", data_files={'train': 'train.parquet', 'test': 'test.parquet'})
要通过 HTTP 加载远程 Parquet 文件,请传递 URL。
>>> base_url = "https://storage.googleapis.com/huggingface-nlp/cache/datasets/wikipedia/20200501.en/1.0.0/"
>>> data_files = {"train": base_url + "wikipedia-train.parquet"}
>>> wiki = load_dataset("parquet", data_files=data_files, split="train")
Arrow
Arrow 文件以内存中的列式格式存储,与基于行的格式(如 CSV)和未压缩格式(如 Parquet)不同。
要加载 Arrow 文件,请执行以下操作:
>>> from datasets import load_dataset
>>> dataset = load_dataset("arrow", data_files={'train': 'train.arrow', 'test': 'test.arrow'})
要通过 HTTP 加载远程 Arrow 文件,请传递 URL。
>>> base_url = "https://storage.googleapis.com/huggingface-nlp/cache/datasets/wikipedia/20200501.en/1.0.0/"
>>> data_files = {"train": base_url + "wikipedia-train.arrow"}
>>> wiki = load_dataset("arrow", data_files=data_files, split="train")
Arrow 是 🤗 Datasets 在幕后使用的文件格式,因此您可以使用 Dataset.from_file() 直接加载本地 Arrow 文件。
>>> from datasets import Dataset
>>> dataset = Dataset.from_file("data.arrow")
与 load_dataset() 不同,Dataset.from_file() 会将 Arrow 文件内存映射,而不会在缓存中准备数据集,从而为您节省磁盘空间。在这种情况下,用于存储中间处理结果的缓存目录将是 Arrow 文件目录。
目前只支持 Arrow 流格式。不支持 Arrow IPC 文件格式(也称为 Feather V2)。
SQL
通过指定连接到您数据库的 URI,使用 from_sql() 读取数据库内容。您可以读取表名和查询。
>>> from datasets import Dataset
# load entire table
>>> dataset = Dataset.from_sql("data_table_name", con="sqlite:///sqlite_file.db")
# load from query
>>> dataset = Dataset.from_sql("SELECT text FROM table WHERE length(text) > 100 LIMIT 10", con="sqlite:///sqlite_file.db")
有关更多详细信息,请查看 如何从 SQL 数据库加载表格数据集 指南。
WebDataset
WebDataset 格式基于 TAR 归档文件,适用于大型图像数据集。由于其大小,WebDatasets 通常以流模式加载(使用 streaming=True
)。
您可以像这样加载 WebDataset:
>>> from datasets import load_dataset
>>>
>>> path = "path/to/train/*.tar"
>>> dataset = load_dataset("webdataset", data_files={"train": path}, split="train", streaming=True)
要通过 HTTP 加载远程 WebDatasets,请传递 URL。
>>> from datasets import load_dataset
>>>
>>> base_url = "https://huggingface.co/datasets/lhoestq/small-publaynet-wds/resolve/main/publaynet-train-{i:06d}.tar"
>>> urls = [base_url.format(i=i) for i in range(4)]
>>> dataset = load_dataset("webdataset", data_files={"train": urls}, split="train", streaming=True)
多进程
当数据集由多个文件(我们称之为“分片”)组成时,可以显着加快数据集下载和准备步骤。
您可以使用 num_proc
选择要并行准备数据集的进程数量。在这种情况下,每个进程都会得到一组分片来准备。
from datasets import load_dataset
imagenet = load_dataset("imagenet-1k", num_proc=8)
ml_librispeech_spanish = load_dataset("facebook/multilingual_librispeech", "spanish", num_proc=8)
内存数据
🤗 数据集还允许您直接从内存数据结构(如 Python 字典和 Pandas DataFrames)创建 数据集。
Python 字典
使用 from_dict() 加载 Python 字典
>>> from datasets import Dataset
>>> my_dict = {"a": [1, 2, 3]}
>>> dataset = Dataset.from_dict(my_dict)
Python 字典列表
使用 from_list()
加载 Python 字典列表
>>> from datasets import Dataset
>>> my_list = [{"a": 1}, {"a": 2}, {"a": 3}]
>>> dataset = Dataset.from_list(my_list)
Python 生成器
使用 from_generator() 从 Python 生成器创建数据集
>>> from datasets import Dataset
>>> def my_gen():
... for i in range(1, 4):
... yield {"a": i}
...
>>> dataset = Dataset.from_generator(my_gen)
此方法支持加载大于可用内存的数据。
您还可以通过将列表传递给 gen_kwargs
来定义分片数据集
>>> def gen(shards):
... for shard in shards:
... with open(shard) as f:
... for line in f:
... yield {"line": line}
...
>>> shards = [f"data{i}.txt" for i in range(32)]
>>> ds = IterableDataset.from_generator(gen, gen_kwargs={"shards": shards})
>>> ds = ds.shuffle(seed=42, buffer_size=10_000) # shuffles the shards order + uses a shuffle buffer
>>> from torch.utils.data import DataLoader
>>> dataloader = DataLoader(ds.with_format("torch"), num_workers=4) # give each worker a subset of 32/4=8 shards
Pandas DataFrame
使用 from_pandas() 加载 Pandas DataFrames
>>> from datasets import Dataset
>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1, 2, 3]})
>>> dataset = Dataset.from_pandas(df)
有关更多详细信息,请查看 如何从 Pandas DataFrames 加载表格数据集 指南。
离线
即使您没有互联网连接,仍然可以加载数据集。只要您之前从 Hub 存储库下载过数据集,它应该会被缓存。这意味着您可以从缓存中重新加载数据集并在离线状态下使用它。
如果您知道没有互联网访问权限,则可以以完全离线模式运行 🤗 数据集。这样可以节省时间,因为 🤗 数据集会直接查看缓存,而不是等待数据集构建器下载超时。将环境变量 HF_HUB_OFFLINE
设置为 1
以启用完全离线模式。
切片拆分
您还可以选择仅加载拆分的特定切片。有两种选择可以切片拆分:使用字符串或 ReadInstruction API。字符串对于简单情况而言更加紧凑且易读,而 ReadInstruction 更易于与可变切片参数一起使用。
通过以下方式连接 train
和 test
拆分
>>> train_test_ds = datasets.load_dataset("bookcorpus", split="train+test")
选择 train
拆分的特定行
>>> train_10_20_ds = datasets.load_dataset("bookcorpus", split="train[10:20]")
或者使用以下方式选择拆分的百分比
>>> train_10pct_ds = datasets.load_dataset("bookcorpus", split="train[:10%]")
选择每个拆分的百分比组合
>>> train_10_80pct_ds = datasets.load_dataset("bookcorpus", split="train[:10%]+train[-80%:]")
最后,您甚至可以创建交叉验证拆分。以下示例创建 10 折交叉验证拆分。每个验证数据集是一个 10% 的块,训练数据集构成剩余的互补 90% 的块
>>> val_ds = datasets.load_dataset("bookcorpus", split=[f"train[{k}%:{k+10}%]" for k in range(0, 100, 10)])
>>> train_ds = datasets.load_dataset("bookcorpus", split=[f"train[:{k}%]+train[{k+10}%:]" for k in range(0, 100, 10)])
百分比切片和舍入
默认行为是将边界舍入到最接近的整数,对于请求的切片边界不能被 100 整除的数据集。如下所示,某些切片可能包含比其他切片更多的示例。例如,如果以下训练拆分包含 999 条记录,则
# 19 records, from 500 (included) to 519 (excluded).
>>> train_50_52_ds = datasets.load_dataset("bookcorpus", split="train[50%:52%]")
# 20 records, from 519 (included) to 539 (excluded).
>>> train_52_54_ds = datasets.load_dataset("bookcorpus", split="train[52%:54%]")
如果您想要大小相等的拆分,请改用 pct1_dropremainder
舍入。这将指定百分比边界视为 1% 的倍数。
# 18 records, from 450 (included) to 468 (excluded).
>>> train_50_52pct1_ds = datasets.load_dataset("bookcorpus", split=datasets.ReadInstruction("train", from_=50, to=52, unit="%", rounding="pct1_dropremainder"))
# 18 records, from 468 (included) to 486 (excluded).
>>> train_52_54pct1_ds = datasets.load_dataset("bookcorpus", split=datasets.ReadInstruction("train",from_=52, to=54, unit="%", rounding="pct1_dropremainder"))
# Or equivalently:
>>> train_50_52pct1_ds = datasets.load_dataset("bookcorpus", split="train[50%:52%](pct1_dropremainder)")
>>> train_52_54pct1_ds = datasets.load_dataset("bookcorpus", split="train[52%:54%](pct1_dropremainder)")
如果数据集中的示例数量不能被 100 整除,pct1_dropremainder
舍入可能会截断数据集中的最后一个示例。
故障排除
有时,在加载数据集时您可能会遇到意外的结果。您可能遇到的两个最常见的问题是手动下载数据集和指定数据集的特征。
手动下载
某些数据集由于许可证不兼容或文件隐藏在登录页面后面,需要您手动下载数据集文件。这会导致 load_dataset() 抛出 AssertionError
。但 🤗 Datasets 提供了详细的说明,帮助您下载缺失的文件。下载完文件后,使用 data_dir
参数指定刚下载文件的路径。
例如,如果您尝试从 MATINF 数据集中下载配置
>>> dataset = load_dataset("matinf", "summarization")
Downloading and preparing dataset matinf/summarization (download: Unknown size, generated: 246.89 MiB, post-processed: Unknown size, total: 246.89 MiB) to /root/.cache/huggingface/datasets/matinf/summarization/1.0.0/82eee5e71c3ceaf20d909bca36ff237452b4e4ab195d3be7ee1c78b53e6f540e...
AssertionError: The dataset matinf with config summarization requires manual data.
Please follow the manual download instructions: To use MATINF you have to download it manually. Please fill this google form (https://forms.gle/nkH4LVE4iNQeDzsc9). You will receive a download link and a password once you complete the form. Please extract all files in one folder and load the dataset with: *datasets.load_dataset('matinf', data_dir='path/to/folder/folder_name')*.
Manual data can be loaded with `datasets.load_dataset(matinf, data_dir='<path/to/manual/data>')
如果您已经从 Hub with a loading script 下载了数据集到您的计算机,那么您需要将绝对路径传递给 data_dir
或 data_files
参数来加载该数据集。否则,如果您传递相对路径,load_dataset() 将从 Hub 上的存储库而不是本地目录加载目录。
指定特征
当您从本地文件创建数据集时,Features 会由 Apache Arrow 自动推断。但是,数据集的特征并不总是符合您的预期,或者您可能希望自己定义特征。以下示例展示了如何使用 ClassLabel 特征添加自定义标签。
首先使用 Features 类定义您自己的标签
>>> class_names = ["sadness", "joy", "love", "anger", "fear", "surprise"]
>>> emotion_features = Features({'text': Value('string'), 'label': ClassLabel(names=class_names)})
接下来,在 load_dataset() 中使用 features
参数指定您刚创建的特征
>>> dataset = load_dataset('csv', data_files=file_dict, delimiter=';', column_names=['text', 'label'], features=emotion_features)
现在,当您查看数据集特征时,您可以看到它使用了您定义的自定义标签
>>> dataset['train'].features
{'text': Value(dtype='string', id=None),
'label': ClassLabel(num_classes=6, names=['sadness', 'joy', 'love', 'anger', 'fear', 'surprise'], names_file=None, id=None)}
(Legacy) 本地加载脚本
您的计算机上可能有一个 🤗 Datasets 加载脚本。在这种情况下,通过将以下路径之一传递给 load_dataset() 来加载数据集
- 加载脚本文件的本地路径。
- 包含加载脚本文件的目录的本地路径(仅当脚本文件与目录同名时)。
传递 trust_remote_code=True
允许 🤗 Datasets 执行加载脚本
>>> dataset = load_dataset("path/to/local/loading_script/loading_script.py", split="train", trust_remote_code=True)
>>> dataset = load_dataset("path/to/local/loading_script", split="train", trust_remote_code=True) # equivalent because the file has the same name as the directory