Spaces:
Sleeping
Sleeping
File size: 3,502 Bytes
240c3a6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
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)
]
|