Datasets 文档

加载 pdf 数据

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

加载 pdf 数据

对 Pdf 的支持是实验性的,可能会发生变化。

Pdf 数据集包含 Pdf 类型的列,其中包含 pdfplumber 对象。

要处理 pdf 数据集,您需要安装 pdfplumber 包。请查阅安装指南了解如何安装。

当您加载一个 pdf 数据集并调用 pdf 列时,pdf 文件会被解码为 pdfplumber 的 Pdf 对象。

>>> from datasets import load_dataset, Pdf

>>> dataset = load_dataset("path/to/pdf/folder", split="train")
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1075bc320>

要索引 pdf 数据集,请先使用行索引,然后再使用 pdf 列 - dataset[0]["pdf"] - 以避免创建数据集中的所有 pdf 对象。否则,如果数据集很大,这会是一个缓慢且耗时的过程。

有关如何加载任何类型数据集的指南,请参阅通用加载指南

读取页面

使用 .pages 属性直接从 pdf 访问页面。

然后您可以使用 pdfplumber 函数来读取文本、表格和图像,例如:

>>> pdf = dataset[0]["pdf"]
>>> first_page = pdf.pages[0]
>>> first_page
<Page:1>
>>> first_page.extract_text()
Docling Technical Report
Version1.0
ChristophAuer MaksymLysak AhmedNassar MicheleDolfi NikolaosLivathinos
PanosVagenas CesarBerrospiRamis MatteoOmenetti FabianLindlbauer
KasperDinkla LokeshMishra YusikKim ShubhamGupta RafaelTeixeiradeLima
ValeryWeber LucasMorin IngmarMeijer ViktorKuropiatnyk PeterW.J.Staar
AI4KGroup,IBMResearch
Ru¨schlikon,Switzerland
Abstract
This technical report introduces Docling, an easy to use, self-contained, MIT-
licensed open-source package for PDF document conversion.
...
>>> first_page.images
In [24]: first_page.images
Out[24]: 
[{'x0': 256.5,
  'y0': 621.0,
  'x1': 355.49519999999995,
  'y1': 719.9952,
  'width': 98.99519999999995,
  'height': 98.99519999999995,
  'name': 'Im1',
  'stream': <PDFStream(44): raw=88980, {'Type': /'XObject', 'Subtype': /'Image', 'BitsPerComponent': 8, 'ColorSpace': /'DeviceRGB', 'Filter': /'DCTDecode', 'Height': 1024, 'Length': 88980, 'Width': 1024}>,
  'srcsize': (1024, 1024),
  'imagemask': None,
  'bits': 8,
  'colorspace': [/'DeviceRGB'],
  'mcid': None,
  'tag': None,
  'object_type': 'image',
  'page_number': 1,
  'top': 72.00480000000005,
  'bottom': 171.0,
  'doctop': 72.00480000000005}]
>>> first_page.extract_tables()
[]

您还可以将每个页面加载为 PIL.Image

>>> import PIL.Image
>>> import io
>>> first_page.to_image()
<pdfplumber.display.PageImage at 0x107d68dd0>
>>> buffer = io.BytesIO()
>>> first_page.to_image().save(buffer)
>>> img = PIL.Image.open(buffer)
>>> img
<PIL.PngImagePlugin.PngImageFile image mode=P size=612x792>

请注意,您可以向 .to_image() 传递 resolution= 参数,以比默认值(72 ppi)更高的分辨率渲染图像。

本地文件

您可以从 pdf 路径加载数据集。使用 cast_column() 函数接受包含 pdf 文件路径的列,并使用 Pdf 特征将其解码为 pdfplumber pdf 对象。

>>> from datasets import Dataset, Pdf

>>> dataset = Dataset.from_dict({"pdf": ["path/to/pdf_1", "path/to/pdf_2", ..., "path/to/pdf_n"]}).cast_column("pdf", Pdf())
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1657d0280>

如果您只想加载 pdf 数据集的底层路径而不解码 pdf 对象,请在 Pdf 特征中设置 decode=False

>>> dataset = dataset.cast_column("pdf", Pdf(decode=False))
>>> dataset[0]["pdf"]
{'bytes': None,
 'path': 'path/to/pdf/folder/pdf0.pdf'}

PdfFolder

您还可以使用 PdfFolder 数据集构建器加载数据集,该构建器无需编写自定义数据加载器。这使得 PdfFolder 非常适合快速创建和加载包含数千个 pdf 文件的 pdf 数据集,以用于不同的视觉任务。您的 pdf 数据集结构应如下所示:

folder/train/resume/0001.pdf
folder/train/resume/0002.pdf
folder/train/resume/0003.pdf

folder/train/invoice/0001.pdf
folder/train/invoice/0002.pdf
folder/train/invoice/0003.pdf

如果数据集遵循 PdfFolder 结构,那么您可以使用 load_dataset() 直接加载它。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")

对于本地数据集,这等同于在 load_dataset() 中手动传递 pdffolder 并在 data_dir 中指定目录。

>>> dataset = load_dataset("pdffolder", data_dir="/path/to/folder")

然后您可以将 pdf 作为 pdfplumber.pdf.PDF 对象来访问。

>>> dataset["train"][0]
{"pdf": <pdfplumber.pdf.PDF at 0x161715e50>, "label": 0}

>>> dataset["train"][-1]
{"pdf": <pdfplumber.pdf.PDF at 0x16170bd90>, "label": 1}

要忽略元数据文件中的信息,请在 load_dataset() 中设置 drop_metadata=True

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)

如果您没有元数据文件,PdfFolder 会自动从目录名称中推断标签名称。如果您想丢弃自动创建的标签,请设置 drop_labels=True。在这种情况下,您的数据集将只包含一个 pdf 列。

>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)

最后,filters 参数允许您根据标签或元数据的条件仅加载数据集的子集。如果元数据是 Parquet 格式,这尤其有用,因为该格式支持快速过滤。还建议将此参数与 streaming=True 一起使用,因为默认情况下,数据集在过滤前会完全下载。

>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)

有关创建您自己的 PdfFolder 数据集的更多信息,请参阅创建 pdf 数据集指南。

Pdf 解码

默认情况下,当您迭代数据集时,pdf 文件会按顺序解码为 pdfplumber PDFs 对象。它会按顺序解码 pdf 的元数据,并且在您访问 pdf 页面之前不会读取它们。

然而,使用多线程解码可以显著加快数据集处理速度。

>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset:  # up to 20 times faster !
...     ...

您可以使用 num_threads 启用多线程。这对于加快远程数据流传输特别有用。但是,对于快速磁盘上的本地数据,它可能比 num_threads=0 慢。

如果您对将文档解码为 pdfplumber PDFs 不感兴趣,而是希望访问路径/字节,您可以禁用解码。

>>> dataset = dataset.decode(False)

注意:目前 IterableDataset.decode() 仅适用于流式数据集。

< > 在 GitHub 上更新