MemoryError при писане на огромен CSV файл

Получавам грешка в паметта всеки път, когато се опитвам да пиша в csv. Така че първите 5 GB данни работят добре, но след това получавам грешка в паметта.

Не знам защо, защото се опитвам да изчистя всеки път своя елемент от паметта, така че да не се случи.

def writeDataCSV(file):
    try:
        with open('Data/csv/'+file+'.csv','w') as fp:
            for evt, elem in iterparse('dumpData/'+str(filename)+'.xml', events=('end',)):
                if elem.tag == 'row':
                    element_fields = elem.attrib
                    data = []

                    if(file== "Comments"):
                        data = commentsXML(element_fields)
                        wr = csv.writer(fp, dialect='excel')
                        wr.writerow(data)
                        elem.clear()
        fp.close
    except UnicodeEncodeError as uniError:
        print(uniError)
    try:
        if(file== "Comments"):
            df = pd.read_csv('Data/csv/Comments.csv', names=["Id","PostId","Score","Text","Date","Time","UserID"])
            df.to_csv("Data/csv/Comments.csv")

     except UnicodeDecodeError as uniDeError:
        print(uniDeError)

MemoryError


person HanahDevelope    schedule 29.05.2018    source източник
comment
Любопитен съм какво се случва, когато затворите своя try/except до частта от кода си, която смятате, че ще се провали. В момента имате 1, който покрива цялата процедура, но може да е само един ред, който се проваля, ако има такъв.   -  person roganjosh    schedule 30.05.2018
comment
Има ли file== "Comments", когато изпълнявате това? Защото изглежда, че сте изяснили само ако случаят е такъв (и кога elem.tag == 'row'). Ако се опитвате да прочетете огромен XML файл, може да искате да започнете, като коментирате част от кода, свързан с CSV, за да стесните къде възниква проблемът.   -  person J. Owens    schedule 30.05.2018
comment
wr = csv.writer никога не се затваря (или промива), особено. ако направите изключение. Винаги е по-добре да отваряте файлове с оператор with .... fp.close не прави нищо, не прави fp.close(), но във всеки случай това трябва да се случи автоматично поради with open(...) as fp, но отново, ако направите изключение, може да не стане. И къде е обработката на други изключения като MemoryError? Преместете оператора си with над стълбата try-except и се уверете, че обработвате други изключения.   -  person smci    schedule 30.05.2018
comment
Както и да е погрешно е да се чете в 5Gb и да се записва, без да се разделя. Използването на паметта ще бъде безумно и ако направите изключение, губите всичко. Какво е commentsXML, откъде идва, колко голям е и какво прави commentsXML(element_fields), търсене ли е?   -  person smci    schedule 30.05.2018
comment
Това е почти дубликат, има много примери за писане на CSV файлове на части, моля, изберете един и затворете това: Как се разделя четенето на голям csv файл на парчета с еднакъв размер в Python? , Как да четем 6 GB csv файл с pandas, Прочетете, форматирайте и след това запишете големи CSV файлове. ..   -  person smci    schedule 30.05.2018
comment
Има 132 посещения за [python] write csv chunk, така че това е дубликат .   -  person smci    schedule 30.05.2018
comment
Получихте MemoryError и си помислихте, че дословното копиране на текста на изключението във въпроса не може да ни помогне?!   -  person Antti Haapala    schedule 30.05.2018
comment
@smci Имаме ли някакъв проблем? Като спам наоколо не помага на общността.   -  person HanahDevelope    schedule 30.05.2018
comment
@AnttiHaapala Получавам изключението в writeDataCSV   -  person HanahDevelope    schedule 30.05.2018
comment
@J.Owens Опитвам се първо да пиша, за да изляза и след това да изчистя паметта (списък с коментари)   -  person HanahDevelope    schedule 30.05.2018
comment
@roganjosh мога да го премахна. Получих UnicodeException, но го поправих   -  person HanahDevelope    schedule 30.05.2018


Отговори (1)


Малко твърде много отговорности във вашата функция, трудно за четене, трудно за отстраняване на грешки, като цяло, не е пример за следване.

Най-доброто ми предположение за избягване на грешка в паметта е да отделя част от кода за четене и запис на собствени функции в стил:

import csv

# FIXME: iterparse, commentsXML are some global functions

def get_data(filename):
    for evt, elem in iterparse('dumpData/'+str(filename)+'.xml', events=('end',)):
        if elem.tag == 'row':
            yield commentsXML(elem.attrib)

def save_stream_to_csv_file(gen, target_csv_filename):
    with open('Data/csv/'+target_csv_filename+'.csv','w') as fp:
        wr = csv.writer(fp, dialect='excel')
        for data in gen:
           wr.writerow(data)

gen = get_data('your_source_filename')
save_stream_to_csv_file(gen, 'your_target_filename')

# WONTFIX: 'dumpData/'+str(filename)+'.xml' and 
#          'Data/csv/'+target_csv_filename+'.csv' are a bit ugly  
#           os.join() and .format() highly welcome
person Evgeny    schedule 29.05.2018
comment
iterparser е импортиране от xml - person HanahDevelope; 30.05.2018
comment
и commentsXML е функция, която ми дава списък за предварителна обработка. - person HanahDevelope; 30.05.2018
comment
Опитвам се да внедря вашия код, но получавам във функцията get_data MemoryError. Мога ли да запиша повече от 5 GB в CSV? - person HanahDevelope; 30.05.2018
comment
CSV файловете не са обвързани с размер, това е просто текстов файл на диск. Има множество връзки по-горе от @smci за това как да управлявате по-големи файлове на парчета. - person Evgeny; 30.05.2018