Как конкатрировать несколько фреймов pandas в один файл данных, который больше памяти?

Я анализирую данные с разделителями табуляции для создания табличных данных, которые я хотел бы хранить в HDF5.

Моя проблема заключается в том, что я должен объединить данные в один формат, а затем сбрасывать в HDF5. Это данные размером ~ 1 ТБ, поэтому я, естественно, не могу поместиться в ОЗУ. Dask может быть лучшим способом выполнить эту задачу.

Если я использую синтаксический анализ своих данных для вставки в один фреймворк pandas, я бы сделал следующее:

import pandas as pd
import csv   

csv_columns = ["COL1", "COL2", "COL3", "COL4",..., "COL55"]
readcsvfile = csv.reader(csvfile)

total_df = pd.DataFrame()    # create empty pandas DataFrame
for i, line in readcsvfile:
    # parse create dictionary of key:value pairs by table field:value, "dictionary_line"
    # save dictionary as pandas dataframe
    df = pd.DataFrame(dictionary_line, index=[i])  # one line tabular data 
    total_df = pd.concat([total_df, df])   # creates one big dataframe

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

import pandas as pd
import csv 
import dask.dataframe as dd
import dask.array as da

csv_columns = ["COL1", "COL2", "COL3", "COL4",..., "COL55"]   # define columns
readcsvfile = csv.reader(csvfile)       # read in file, if csv

# somehow define empty dask dataframe   total_df = dd.Dataframe()? 
for i, line in readcsvfile:
    # parse create dictionary of key:value pairs by table field:value, "dictionary_line"
    # save dictionary as pandas dataframe
    df = pd.DataFrame(dictionary_line, index=[i])  # one line tabular data 
    total_df = da.concatenate([total_df, df])   # creates one big dataframe

После создания фрейма данных TB, я сохраню в hdf5.

Моя проблема в том, что total_df не вписывается в ОЗУ и должен быть сохранен на диске. Может ли dask dataframe выполнить эту задачу?

Должен ли я попробовать что-то еще? Было бы проще создать HDF5 из множества массивов dask, т.е. Каждый столбец/поле представляет собой массив dask? Может быть, разделяем числовые кадры между несколькими узлами и уменьшаем их в конце?

EDIT: для ясности я фактически не читаю непосредственно из файла csv. Я агрегирую, разбор и форматирование табличных данных. Итак, readcsvfile = csv.reader(csvfile) используется выше для ясности/краткости, но это намного сложнее, чем чтение в CSV файле.

Ответ 1

Dask.dataframe обрабатывает массивы данных, отличные от памяти, через лень. Добавление конкретных данных в файл dask.dataframe не будет продуктивным.

Если ваши данные могут обрабатываться pd.read_csv

Функция pandas.read_csv очень гибкая. Вы говорите выше, что ваш процесс синтаксического анализа очень сложный, но все же стоит посмотреть варианты pd.read_csv, чтобы увидеть, будет ли он работать. Функция dask.dataframe.read_csv поддерживает те же самые аргументы.

В частности, если вы обеспокоены тем, что ваши данные разделены вкладками, а не запятыми, это не проблема. Pandas поддерживает ключевое слово sep='\t', а также несколько десятков других параметров.

Рассмотрим dask.bag

Если вы хотите последовательно работать с текстовыми файлами, рассмотрите возможность использования dask.bag для анализа ваших данных, начиная с кучи текста.

import dask.bag as db
b = db.read_text('myfile.tsv', blocksize=10000000)  # break into 10MB chunks
records = b.str.split('\t').map(parse)
df = records.to_dataframe(columns=...)

Запись в файл HDF5

Как только у вас есть dask.dataframe, попробуйте метод .to_hdf:

df.to_hdf('myfile.hdf5', '/df')