2013-08-21 1 views
0

Знаете ли вы, что библиотеки Python хороши для хранения больших неструктурированных списков (например, a=[0,numpy.asarray([1,2,3])])?Хранение большого неструктурированного списка в Python

То, что я видел до сих пор, h5py не поддерживает данные такого рода, и рассол кажется медленным. Любые другие альтернативы?

Для моей цели мы можем предположить, что я имею дело с данными одного типа (массивы numpy с типом int), но с другой формой.

+3

Вы использовали cPickle или регулярный рассол? – user2357112

+0

Возможный дубликат [лучший способ сохранения массивов numpy на диске] (http://stackoverflow.com/questions/9619199/best-way-to-preserve-numpy-arrays-on-disk) –

+0

@SlaterTyranus Я не подумайте, что это дубликат, так как он не хранит массивы 'numpy'. В этом примере он дал ему также скалярные значения и, может быть, кто знает что. В целом, я думаю, что это немного более общий вопрос, чем просто хранение массивов 'numpy'. –

ответ

0

На самом деле вы можете хранить и извлекать данные такого рода в hdf5 файл с только немного пользовательской логики:

import tables 
import numpy as np 

def store(filename, name, data): 
    with tables.openFile(filename, 'w') as store: 
     store.createGroup('/', name) 
     for i, item in enumerate(data): 
      store.createArray('/%s' % name, 'item_%s' % i, item) 

def read(filename, name): 
    with tables.openFile(filename, 'r') as store: 
     nodes = store.listNodes('/%s' % name) 
     data = [0] * len(nodes) 
     for node in nodes: 
      pos = int(node.name.split('_')[-1]) 
      data[pos] = node.read() 
     return data 

Использование:

>>> a = [0, np.array([4,5,6])] 
>>> store('my_data.h5', 'a', a) 
>>> print read('my_data.h5', 'a') 
[0, array([4, 5, 6])] 

Это только первая вещь которые падают на мой взгляд, я уверен, что есть более эффективный шаблон хранения списка в hdf5 файлах. Но давайте раз и посмотреть, если даже эта наивная реализация быстрее, чем cPickle:

In [7]: a = [] 
     for i in range(1, 500): 
      if i % 10 == 0: 
       a.append(i) 
      else: 
       a.append(np.random.randn(i, i)) 
In [8]: %%timeit 
     store('my_data.h5', 'a', a) 
     read_data = read('my_data.h5', 'a') 
1 loops, best of 3: 1.32 s per loop 
In [9]: %%timeit 
     with open('test.pickle', 'wb') as f: 
      cPickle.dump(a, f) 
     with open('test.pickle', 'rb') as f: 
      read_data = cPickle.load(f) 
1 loops, best of 3: 1min 58s per loop 

В зависимости от данных разница еще больше или немного меньше. Но даже эта глупая реализация по крайней мере в 10 раз быстрее, чем cPickle для любых данных, содержащих numpy массивов.

+0

Ухоженный, и очень близко к тому, что мне нужно. Большое спасибо. – m4linka

0

Если вы считаете, что Pickle и cPickle слишком медленные, вы должны изучить либо Marshall, либо Shelve, поскольку они являются двумя другими крупными стандартными библиотеками сериализации. Если это не сработает для вас, вы захотите начать использовать законную базу данных.

В конце концов, способность хранить и извлекать большие объемы данных быстро - это в основном база данных, и эти модули сжатия будут только доводить вас до этого. Если бы они были идеальными, вам не нужны базы данных.

Если вы не хотите использовать ни один из них, на самом деле есть инструменты, специально предназначенные для этой цели, но я чувствую, что это будет одноразовый. Вы можете посмотреть here для одного такого сервиса, но есть еще пара.

Смежные вопросы