Datasets documentation

加载 pdf 数据

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v4.8.4).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

加载 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>

请注意,您可以将 resolution= 传递给 .to_image(),以高于默认值(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 数据集构建器加载数据集,这无需编写自定义 dataloader。这使得 PdfFolder 非常适合快速创建和加载包含数千个 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() 目前仅适用于流式数据集。

Update on GitHub