Как добавить большие объемы данных в Pandas HDFStore и получить уникальный уникальный индекс?
Я импортирую большое количество журналов http (80GB +) в хранилище HDFStore Pandas для статистической обработки. Даже в одном файле импорта мне нужно загрузить содержимое при загрузке. Моя тактика до сих пор заключалась в том, чтобы прочитать анализируемые строки в DataFrame, а затем сохранить DataFrame в HDFStore. Моя цель состоит в том, чтобы ключ индекса был уникальным для одного ключа в DataStore, но каждый DataFrame снова перезапускает свое значение индекса. Я ожидал, что HDFStore.append() будет иметь некоторый механизм, чтобы сказать ему игнорировать значения индекса DataFrame и просто добавлять к моим существующим значениям ключевых слов HDFStore, но не может их найти. Как импортировать DataFrames и игнорировать содержащиеся в нем значения индекса, а HDFStore увеличивает его существующие значения индекса? Примерный пример ниже, каждые 10 строк. Естественно, реальная вещь будет больше.
if hd_file_name:
"""
HDF5 output file specified.
"""
hdf_output = pd.HDFStore(hd_file_name, complib='blosc')
print hdf_output
columns = ['source', 'ip', 'unknown', 'user', 'timestamp', 'http_verb', 'path', 'protocol', 'http_result',
'response_size', 'referrer', 'user_agent', 'response_time']
source_name = str(log_file.name.rsplit('/')[-1]) # HDF5 Tables don't play nice with unicode so explicit str(). :(
batch = []
for count, line in enumerate(log_file,1):
data = parse_line(line, rejected_output = reject_output)
# Add our source file name to the beginning.
data.insert(0, source_name )
batch.append(data)
if not (count % 10):
df = pd.DataFrame( batch, columns = columns )
hdf_output.append(KEY_NAME, df)
batch = []
if (count % 10):
df = pd.DataFrame( batch, columns = columns )
hdf_output.append(KEY_NAME, df)
Ответы
Ответ 1
Вы можете сделать это так. Только трюк заключается в том, что в первый раз таблица хранилища не существует, поэтому get_storer
будет повышаться.
import pandas as pd
import numpy as np
import os
files = ['test1.csv','test2.csv']
for f in files:
pd.DataFrame(np.random.randn(10,2),columns=list('AB')).to_csv(f)
path = 'test.h5'
if os.path.exists(path):
os.remove(path)
with pd.get_store(path) as store:
for f in files:
df = pd.read_csv(f,index_col=0)
try:
nrows = store.get_storer('foo').nrows
except:
nrows = 0
df.index = pd.Series(df.index) + nrows
store.append('foo',df)
In [10]: pd.read_hdf('test.h5','foo')
Out[10]:
A B
0 0.772017 0.153381
1 0.304131 0.368573
2 0.995465 0.799655
3 -0.326959 0.923280
4 -0.808376 0.449645
5 -1.336166 0.236968
6 -0.593523 -0.359080
7 -0.098482 0.037183
8 0.315627 -1.027162
9 -1.084545 -1.922288
10 0.412407 -0.270916
11 1.835381 -0.737411
12 -0.607571 0.507790
13 0.043509 -0.294086
14 -0.465210 0.880798
15 1.181344 0.354411
16 0.501892 -0.358361
17 0.633256 0.419397
18 0.932354 -0.603932
19 -0.341135 2.453220
На самом деле вам необязательно нужен глобальный уникальный индекс (если вы этого не хотите), поскольку HDFStore
(через PyTables
) предоставляет одно значение для однозначной нумерации строк. Вы всегда можете добавить эти параметры выбора.
In [11]: pd.read_hdf('test.h5','foo',start=12,stop=15)
Out[11]:
A B
12 -0.607571 0.507790
13 0.043509 -0.294086
14 -0.465210 0.880798