Преобразование больших csv в hdf5
у меня есть csv-файл 100M (на самом деле много отдельных csv-файлов) на общую сумму 84 ГБ. Мне нужно преобразовать его в файл HDF5 с одним набором данных float. Я использовал h5py в тестировании без каких-либо проблем, но теперь я не могу сделать окончательный набор данных без нехватки памяти.
как я могу писать в HDF5 без необходимости хранить весь набор данных в памяти? Я ожидаю здесь фактического кода, потому что он должен быть довольно простым.
Я просто смотрел в pytables, но не похоже, что класс array (который соответствует набору данных HDF5) может быть записан итеративно. Аналогично,панды и read_csv
и to_hdf
методы в своей io_tools
, но я не могу загрузить весь набор данных за один раз, так что не будет работать. Возможно, вы можете помочь мне правильно решить проблему с другими инструментами в pytables или панды.
2 ответов
использовать append=True
в вызове to_hdf
:
import numpy as np
import pandas as pd
filename = '/tmp/test.h5'
df = pd.DataFrame(np.arange(10).reshape((5,2)), columns=['A', 'B'])
print(df)
# A B
# 0 0 1
# 1 2 3
# 2 4 5
# 3 6 7
# 4 8 9
# Save to HDF5
df.to_hdf(filename, 'data', mode='w', format='table')
del df # allow df to be garbage collected
# Append more data
df2 = pd.DataFrame(np.arange(10).reshape((5,2))*10, columns=['A', 'B'])
df2.to_hdf(filename, 'data', append=True)
print(pd.read_hdf(filename, 'data'))
доходность
A B
0 0 1
1 2 3
2 4 5
3 6 7
4 8 9
0 0 10
1 20 30
2 40 50
3 60 70
4 80 90
обратите внимание, что вы должны использовать format='table'
в первом вызове df.to_hdf
сделать таблицу appendable. В противном случае формат 'fixed'
по умолчанию, что быстрее для чтения и записи, но создает таблицу, к которой нельзя добавить.
таким образом, вы можете обрабатывать каждый CSV по одному, используйте append=True
создать файл hdf5. Затем перезапишите фрейм данных или использовать del df
чтобы позволить старому фрейму данных быть собранным мусором.
альтернативно, вместо вызова df.to_hdf
, можно добавить в HDFStore:
import numpy as np
import pandas as pd
filename = '/tmp/test.h5'
store = pd.HDFStore(filename)
for i in range(2):
df = pd.DataFrame(np.arange(10).reshape((5,2)) * 10**i, columns=['A', 'B'])
store.append('data', df)
store.close()
store = pd.HDFStore(filename)
data = store['data']
print(data)
store.close()
доходность
A B
0 0 1
1 2 3
2 4 5
3 6 7
4 8 9
0 0 10
1 20 30
2 40 50
3 60 70
4 80 90
это должно быть возможно с помощью PyTables. Вам нужно будет использовать EArray классе, хотя.
в качестве примера ниже приведен сценарий, который я написал для импорта фрагментированных данных обучения, хранящихся как .npy
файлы в один .
import numpy
import tables
import os
training_data = tables.open_file('nn_training.h5', mode='w')
a = tables.Float64Atom()
bl_filter = tables.Filters(5, 'blosc') # fast compressor at a moderate setting
training_input = training_data.create_earray(training_data.root, 'X', a,
(0, 1323), 'Training Input',
bl_filter, 4000000)
training_output = training_data.create_earray(training_data.root, 'Y', a,
(0, 27), 'Training Output',
bl_filter, 4000000)
for filename in os.listdir('input'):
print "loading {}...".format(filename)
a = numpy.load(os.path.join('input', filename))
print "writing to h5"
training_input.append(a)
for filename in os.listdir('output'):
print "loading {}...".format(filename)
training_output.append(numpy.load(os.path.join('output', filename)))
взгляните на документы для получения подробных инструкций, но очень кратко,create_earray
функция принимает 1) корень данных или родительский узел; 2) имя массива; 3) атом типа данных; 4) фигуру с 0
в размер вы хотите развернуть; 5) подробный дескриптор; 6) a фильтр сжатия; и 7) ожидаемое количество строк по расширяемый размер. Только первые два необходимы, но вы, вероятно, будете использовать все семь на практике. Функция также принимает несколько других необязательных аргументов; для получения дополнительной информации см. документы.
после создания массива, вы можете использовать append
метод ожидаемым способом.