Spaces:
Sleeping
Sleeping
import fitz | |
from tqdm.auto import tqdm | |
from spacy.lang.en import English | |
def text_formatter(text: str) -> str: | |
""" | |
Formatea el texto extraído de un PDF eliminando saltos de línea | |
y espacios sobrantes. | |
""" | |
return text.replace("\n", " ").strip() | |
def read_pdf(pdf_bytes: bytes) -> list[dict]: | |
""" | |
Lee un archivo PDF a partir de sus bytes y extrae información de cada página: | |
- Número de página | |
- Conteo de caracteres | |
- Conteo de palabras | |
- Conteo aproximado de oraciones (separadas por '. ') | |
- Conteo de tokens aproximado (asumiendo 1 token ~ 4 caracteres) | |
- Texto completo de la página | |
Parámetros: | |
----------- | |
pdf_bytes : bytes | |
Contenido binario de un PDF. | |
Retorna: | |
-------- | |
list[dict] | |
Lista de diccionarios con la información de cada página. | |
""" | |
doc = fitz.open(stream=pdf_bytes, filetype="pdf") | |
pages_and_text = [] | |
for page_number, page in tqdm(enumerate(doc), desc="Leyendo PDF"): | |
text = page.get_text() | |
text = text_formatter(text=text) | |
pages_and_text.append( | |
{ | |
"page_number": page_number + 1, | |
"page_char_count": len(text), | |
"page_word_count": len(text.split(" ")), | |
"page_sentence_count_raw": len(text.split(". ")), | |
"page_token_count": len(text) / 4, # Estimación aproximada | |
"text": text, | |
} | |
) | |
return pages_and_text | |
def process_chunks(pages_and_text: list[dict]) -> list[dict]: | |
""" | |
Procesa cada página para dividir el texto en oraciones y luego agrupar | |
esas oraciones en 'chunks' de 10 oraciones cada uno. | |
Parámetros: | |
----------- | |
pages_and_text : list[dict] | |
Lista de diccionarios que contienen el texto y metadatos de cada página. | |
Retorna: | |
-------- | |
list[dict] | |
Lista de diccionarios donde cada diccionario representa un chunk de oraciones. | |
""" | |
nlp = English() | |
nlp.add_pipe("sentencizer") | |
# Dividir el texto en oraciones | |
for item in tqdm(pages_and_text, desc="Dividiendo en oraciones"): | |
item["sentences"] = [str(sent) for sent in nlp(item["text"]).sents] | |
item["sentence_chunks"] = split_list(item["sentences"], 10) | |
item["num_of_chunks"] = len(item["sentence_chunks"]) | |
# Crear una lista de todos los chunks | |
pages_and_chunks = [] | |
for item in tqdm(pages_and_text, desc="Creando 'chunks'"): | |
for sentence_chunk in item["sentence_chunks"]: | |
chunk_dict = { | |
"page_number": item["page_number"], | |
"sentence_chunk": " ".join(sentence_chunk).strip(), | |
"chunk_word_count": sum(len(sentence.split()) for sentence in sentence_chunk), | |
"chunk_token_count": sum(len(sentence) for sentence in sentence_chunk) / 4, | |
} | |
pages_and_chunks.append(chunk_dict) | |
return pages_and_chunks | |
def split_list(input_list: list[str], slice_size: int) -> list[list[str]]: | |
""" | |
Divide una lista en sublistas de tamaño determinado. | |
Parámetros: | |
----------- | |
input_list : list[str] | |
Lista original que se desea dividir. | |
slice_size : int | |
Tamaño de cada sublista. | |
Retorna: | |
-------- | |
list[list[str]] | |
Lista de sublistas, cada una con una longitud máxima de 'slice_size'. | |
""" | |
return [ | |
input_list[i : i + slice_size] for i in range(0, len(input_list), slice_size) | |
] | |