Управление некоторыми значениями в списке в Python - PullRequest
1 голос
/ 29 марта 2020

Позвольте мне постараться объяснить, насколько я могу, поскольку я не волшебник Python. Я прочитал с PyPDF2 таблицу данных PDF о covid-19 в Мексике и разложил ее по токенам - длинная история, я попытался сделать это с помощью tabula, но не получил ожидаемый формат, и я собирался потратить больше времени на переформатирование документа CSV Я вернулся, чем анализировал его, и получил список строк с len 16792, и это нормально.

Теперь проблема, с которой я сталкиваюсь, заключается в том, что мне нужно отформатировать ее соответствующим образом, объединяя некоторые (не все) из этих строк вместе, чтобы я мог создать список списков одинаковой длины, равной 9 колонны.

Это пример того, как это выглядит сейчас, столбцы: Номер дела, Штат, Местность, Пол, Возраст, Дата появления симптомов, Статус, Тип заражения, Дата прибытия в Мексику:

['1', 'PUEBLA', 'PUEBLA', 'M', '49', '15/03/2020', 'Sospechoso', 'Contacto', 'NA', '2', 'GUERRERO', 'ZONA', 'NORTE', 'M', '29', '15/03/2020', 'Sospechoso', 'Contacto', 'NA', '3', 'BAJA', 'CALIFORNIA', 'TIJUANA', 'F', '34', '14/03/2020', 'Sospechoso', 'Estados', 'Unidos', '08/03/2020', '4', 'CIUDAD', 'DE', 'MÉXICO', 'TLALPAN', 'F', '69', '25/02/2020', 'Sospechoso', 'Italia', '03/03/2020', '5', 'JALISCO', 'CENTRO', 'GUADALAJARA', 'M', '19', '18/03/2020', 'Sospechoso', 'España', '17/03/2020'

Я хотел бы получить определенные строки, такие как 'ZONA', 'NORTE' как 'ZONA NORTE' или 'CIUDAD', 'DE', 'MEXICO' как 'CIUDAD DE MEXICO' или 'ESTADOS ',' UNIDOS 'как' ESTADOS UNIDOS '...

Я серьезно не знаю, как с этим справиться. Я пытался, split (), replace (), пытался найти индекс каждой частоты, прочитал все вопросы о работе со списками, перепробовал почти все предоставленные ответы ... и не смог этого сделать.

Любое руководство, будет принята с благодарностью. Извините, если это очень простой вопрос, но я знаю, что должен быть способ, я просто не знаю его.

Ответы [ 2 ]

0 голосов
/ 29 марта 2020

Saludos. Bienvenida a StackOverflow.

Я предполагаю, что данные, которые вы хотите обработать, поступают из файла, подобного этому здесь , который содержит 2623 строки x 8 столбцов.

Вы можете загрузить данные из файла PDF, используя tabula-py. Вы можете установить его через pip install tabula-py==1.3.0. Одна из проблем с извлечением таблицы, подобной этой, заключается в том, что tabula-py иногда может что-то испортить. Например, заголовок таблицы был извлечен из файла PDF следующим образом:

"" ,,,, Identificación Fecha de,
"" ,,,, de COVID-19, Fecha del llegada a
N ° Caso, Estado, Sexo, Edad, Inceio de Procedencia por RT-PCR en, México
"" ,,,, síntomas,
"" ,,,, tiempo real,

Довольно неприятно, да?

Кроме того, tabula-py не может разделить некоторые столбцы, то есть записывать запятую в нужном месте так, чтобы выходной файл CSV будет хорошо проанализирован. Например, строку с número de caso (номер дела) 8:

8,BAJA CALIFORNIA,F,65,13/03/2020 Sospechoso Estados Unidos,08/03/2020

можно исправить, просто заменив «Sospechoso» на «Sospechoso, ». И вам повезло, потому что это единственная проблема разбора, с которой вам придется иметь дело на данный момент. Таким образом, перебирая строки выходного CSV-файла и заменяя «Sospechoso» на «Sospechoso», позаботимся обо всем.

Наконец, я добавил опцию (removeaccents) для удаления акцентов из данные. Это может помочь вам избежать проблем с кодированием в будущем. Для этого вам понадобится Unicode: pip install unidecode.

Собирая все вместе, код, который читает файл PDF и преобразует его в файл CSV и загружает его в виде pandas кадра данных, выглядит следующим образом ( Вы можете загрузить предварительно обработанный файл CSV здесь ):

import tabula
from tabula import wrapper
import pandas as pd
import unidecode

"""
1. Adds the header.
2. Skips "corrupted" lines from tabula.
3. Replacing " Sospechoso " for ",Sospechoso," automatically separates
the previous column ("fecha_sintomas") from the next one ("procedencia").
4. Finally, elminiates accents to avoid encoding issues.
"""
def simplePrep( 
                input_path,
                header = [
                            "numero_caso",
                            "estado",
                            "sexo",
                            "edad",
                            "fecha_sintomas",
                            "identification_tiempo_real",
                            "procedencia",
                            "fecha_llegada_mexico"
                        ],
                lookfor = " Sospechoso ",
                replacewith = ",Sospechoso,",
                output_path = "preoprocessed.csv",
                skiprowsupto = 5,
                removeaccents = True
                ):
    fin = open(input_path, "rt")
    fout = open(output_path, "wt")

    fout.write(",".join(header) + "\n")

    count = 0

    for line in fin:
        if count > skiprowsupto - 1:
            if removeaccents:
                fout.write(unidecode.unidecode(line.replace(lookfor, replacewith)))
            else:
                fout.write(line.replace(lookfor, replacewith))

        count += 1

    fin.close()
    fout.close()

"""
Reads all the pdf pages specifying that the table spans multiple pages.
multiple_tables = True, otherwise the first row of each page will be missed.
"""
tabula.convert_into(
                        input_path = "data.pdf",
                        output_path = "output.csv",
                        output_format = "csv",
                        pages = 'all',
                        multiple_tables = True
                    )

simplePrep("output.csv", removeaccents = True)

# reads preprocess data set
df = pd.read_csv("preoprocessed.csv", header = 0)

# prints the first 5 samples in the dataframe
print(df.head(5))
0 голосов
/ 29 марта 2020

Поскольку фраза не одинакова для каждой строки, у вас есть способ «распознать» ее. Одним из способов было бы, если 2 элемента списка, которые находятся рядом друг с другом, имеют более 3 букв, а затем соедините их.

import re
row_list = ['1', 'PUEBLA', 'PUEBLA', 'M', '49', '15/03/2020', 'Sospechoso', 'Contacto', 'NA', '2', 'GUERRERO', 'ZONA', 'NORTE', 'M', '29', '15/03/2020', 'Sospechoso', 'Contacto', 'NA', '3', 'BAJA', 'CALIFORNIA', 'TIJUANA', 'F', '34', '14/03/2020', 'Sospechoso', 'Estados', 'Unidos', '08/03/2020', '4', 'CIUDAD', 'DE', 'MÉXICO', 'TLALPAN', 'F', '69', '25/02/2020', 'Sospechoso', 'Italia', '03/03/2020', '5', 'JALISCO', 'CENTRO', 'GUADALAJARA', 'M', '19', '18/03/2020', 'Sospechoso', 'España', '17/03/2020']
words_longer_than_3 = r'([^\d\W]){3,}'


def is_a_word(text):
    return bool(re.findall(words_longer_than_3, text))


def get_next_item(row_list, i):
    try:
        next_item = row_list[i+1]
    except IndexError:
        return
    return is_a_word(next_item)


for i, item in enumerate(row_list):
    item_is_a_word = is_a_word(row_list[i])
    if not item_is_a_word:
        continue
    next_item_is_a_word = get_next_item(row_list, i)
    while next_item_is_a_word:
        row_list[i] += f' {row_list[i+1]}'
        del row_list[i+1]
        next_item_is_a_word = get_next_item(row_list, i)

print(row_list)

результат:

['1', 'PUEBLA PUEBLA', 'M', '49', '15/03/2020', 'Sospechoso Contacto', 'NA', '2', 'GUERRERO ZONA NORTE', 'M', '29', '15/03/2020', 'Sospechoso Contacto', 'NA', '3', 'BAJA CALIFORNIA TIJUANA', 'F', '34', '14/03/2020', 'Sospechoso Estados Unidos', '08/03/2020', '4', 'CIUDAD', 'DE', 'MÉXICO TLALPAN', 'F', '69', '25/02/2020', 'Sospechoso Italia', '03/03/2020', '5', 'JALISCO CENTRO GUADALAJARA', 'M', '19', '18/03/2020', 'Sospechoso España', '17/03/2020']
...