Как конкатрировать несколько фреймов 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')