Как повысить скорость кода: преобразование большого XML-файла в формат данных - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть 2,5 ГБ XML-файл, который мне нужно преобразовать в фрейм данных

Вот что я делаю: прежде всего я нарезал и сохранил начальный и конечный индексы каждого элемента.Таким образом, список будет выглядеть примерно так:

[[(1 100), [101 158), ......., (1911,2098)], [(2099,2300), [2301,2358), ......., (2911,3091)] .......................... [(1000000001,1000000099),(1000000401,1000000899), ......., (2000000001,2000000099)]]

По сути, список представляет собой список списков, каждый из которых содержит 1000 элементов, где каждый элемент находится вформа (start_index, end_index)

Теперь я написал рекурсивную функцию (все коды в python), которая при запуске на одном разделе полного элемента XML (ровно на одном (start_index, end_index)) выдаетсловарь вместе с преобразованием его в датафрейм.

Теперь, что я сделал, я запустил этот код для цикла for для каждого списка, содержащего 1000 индексов, и продолжаю преобразовывать его в словарь и добавлять его в первоначально пустой фрейм данных.Когда ровно один список закончен, я добавляю его в основной фрейм данных (изначально пустой).Таким образом, у нас есть ровно 1000 записей в кадре данных на первом внешнем цикле for.и постепенно у нас есть 1000 дополнительных записей для каждого цикла.Проблема, однако, в том, что каждый цикл for работает в 1500 раз, и при каждом запуске время увеличивается (странно, поскольку при каждом запуске он обрабатывает только 1000 раз).Таким образом, потребуется целая вечность, чтобы закончить.Может кто-нибудь рассказать об улучшении этого кода или о другом подходе в целом?


''''helping functions including the recursion function'''

import itertools 
import pandas as pd
from tabulate import tabulate

def opening_start_idx(line):
    for n,word in enumerate(line):
        if word=="<":
            return n+5    



def closing_start_idx(line):
    flag=0

    for n,word in enumerate(line):
        if word=='<':
            if flag==1:
                return n+6
            else:
                flag=flag+1



def opening_end_idx(line):
    for n,word in enumerate(line):
        if word=='>':
            return n


def recursive_xmltoDict(final_dict,strt,content,parent_id):
            for n,line in enumerate(content):
                if "<lei:" in line and '</lei:' in line:
                    final_dict[parent_id+"."+line[opening_start_idx(line):opening_end_idx(line)].partition(' ')[0]]=[line[opening_end_idx(line)+1 : closing_start_idx(line)-6 ]]
                elif "<lei:" in line and '</lei:' not in line:
                    recursive_xmltoDict(final_dict,n+1,content,parent_id+"."+line[opening_start_idx(line):opening_end_idx(line)].partition(' ')[0])
                elif "<lei:" not in line and '</lei:' in line:
                    return
                else:
                    print(line,"there is some other case we missed")

            return




'''final For loop to be run with above helping functions'''

df_final=pd.DataFrame()

for n,all_blocks in enumerate(listOlist):
    start = time.time()
    df2=pd.DataFrame() 
    for slices in all_blocks:
        full_content=open(inputfile,encoding="utf8")
        #print(slices[0],slices[1])
        final_dict={}
        content=itertools.islice(full_content,slices[0],slices[1])
        #for line in content:
            #print(line)
        parent_id=""
        recursive_xmltoDict(final_dict,0,content,parent_id)
        df3=pd.DataFrame(final_dict)
        #print(df1)
        df2=pd.concat([df2,df3],sort=False)
    df_final=pd.concat([df_final,df2],sort=False)
    end = time.time()
    print("Time taken for nth",n,"iteration is", end - start)


Время, необходимое для n-й итерации 0, составляет 25,71298122406006

Время, необходимое для N-й итерации 1, составляет 54,34917497634888

Время, необходимое для n-й 2-й итерации: 84,38950777053833

Время, необходимое для n-й 3-й итерации: 110,95254158973694

Время, необходимое для N-й 4-й итерации: 145.15516877174377

Время, необходимое для N-й 5-й итерации, равно146.04912757873535

Время, необходимое для n-й итерации 6, составляет 160,33096170425415

Время, необходимое для итерации N-й 7, составляет 182,26985692977905

и вечность ......

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...