Пакетирование файлов в списке в подсписки на основе порогового размера памяти DataFrame - PullRequest
0 голосов
/ 11 февраля 2020

Я хотел бы найти способ пакетировать большой список файлов в подсписки, каждый из которых имеет ограничение на память, хранящуюся в форме DataFrame.

Код просто переворачивается считывает файлы как DataFrames и использует pd.concat() для их объединения.

Псевдокод выглядит следующим образом:

in_dir = C:\some_directory
list_files = os.listdir(in_dir)

files_df = pd.DataFrame()

for file in list_files:
   file_df = pd.read_csv(file)
   files_df = pd.concat([files_df, file_df])

Проблема заключается в том, что при объединении больших файлов это приводит к MemoryError - Unable to allocate array with shape xxxx.

Желаемые входы и выходы будут:

input

list_files = [file_1.csv, file_2.csv, file_3.csv, file_4.csv . . . file_n.csv]

output

list_files_memory = [[file_2.csv, file_5.csv ...], [file_56.csv, file_4.csv ...], ....]

Где каждый подсписок имеет memory_df <= total available memory.

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

Я сделал некоторый код для пакета в размере чанка:

def chunk_files(input_list, chunk_size):
    """chunk file list into chunk_size-sublists of equal size + leftovers

    inputs
    -------
    input_list (list) : total list to be broken up
    chunk_size (int) : number of elements/files per sublist

    outputs
    -------
    chunked_list (list) : output list that has been chunked

    """
    chunked_list = []  # append list

    # break into n-many sublists based off file number
    sublist_num = int(len(input_list)/chunk_size)

    # iterate over sublists
    for sublist_batch in range(0, len(input_list), sublist_num):
        # grab number of elements per chunk
        chunk_list = input_list[sublist_batch: sublist_batch + sublist_num]

        # if chunked list equal to sublist_num
        if len(chunk_list) % sublist_num == 1:
            chunked_list[-1].extend(chunk_list)

        # if chunked list has remainder/leftovers
        else:
            chunked_list.append(chunk_list)

    return chunked_list

Эта функция создает только пакеты на основе определенного размера chunk_size (или количества файлов в пакете), а не ограничений на размер файла в пакете.

Еще один нюанс заключается в том, что могут быть файлы, названные в основном такими же, как я хотел бы в один пакет (ie: одно и то же имя для file_1_EM1.csv и file_1_EM2.csv, которое я хотел бы сохранить в одном пакете).

Есть ли способ сделать это с помощью os.path.getsize() или любого другого методы?

...