PyTables - большое потребление памяти методом cols - PullRequest
0 голосов
/ 20 марта 2019

Какова цель использования метода cols в Pytables? У меня большой набор данных, и мне интересно читать только один столбец из этого набора данных.

Эти два метода дают мне одно и то же время, но совершенно разное потребление переменной памяти:

import tables
from sys import getsizeof

f = tables.open_file(myhdf5_path, 'r')

# These two methods takes the same amount of time
x = f.root.set1[:500000]['param1']
y = f.root.set1.cols.param1[:500000]

# But totally different memory consumption:
print(getsizeof(x)) # gives me 96
print(getsizeof(y)) # gives me 2000096

Они оба имеют одинаковый тип данных массива. Кто-нибудь может объяснить мне, какова цель использования метода cols?

%time x = f.root.set1[:500000]['param1']  # gives ~7ms
%time y = f.root.set1.cols.param1[:500000]  # gives also about 7ms

1 Ответ

0 голосов
/ 20 марта 2019

Ваш вопрос заинтересовал меня.Я обычно использую table.read(field='name'), потому что он дополняет другие методы table.read_, которые я использую (например: .read_where() и .read_coordinates()).

Послепросматривая документы, я нашел по крайней мере 4 способа чтения одного столбца данных таблицы с помощью PyTables.Вы показали 2, и есть еще 2:
table.read(field='name')
table.col('name') (единственное число)

Я провел несколько тестов со всеми 4, плюс 2 теста на всю таблицу (набор данных) для дополнительных сравнений.Я назвал getsizeof() для всех 6 объектов, и размер варьируется в зависимости от метода.Хотя все 4 ведут себя одинаково с индексами NumPy, я подозреваю, что есть разница в возвращаемом объекте.Однако я не разработчик PyTables, так что это скорее вывод, чем факт.Также возможно, что getsizeof() интерпретирует объект по-разному.

Код ниже:

import tables as tb
import numpy as np
from sys import getsizeof

# Create h5 file with 1 dataset

h5f = tb.open_file('SO_55254831.h5', 'w')

mydtype = np.dtype([('param1',float),('param2',float),('param3',float)])

arr = np.array(np.arange(3.*500000.).reshape(500000,3))
recarr = np.core.records.array(arr,dtype=mydtype)

h5f.create_table('/', 'set1', obj=recarr )

# Close, then Reopen file READ ONLY
h5f.close()

h5f = tb.open_file('SO_55254831.h5', 'r')

testds_1 = h5f.root.set1
print ("\nFOR: testds_1 = h5f.root.set1")
print (testds_1.dtype)
print (testds_1.shape)
print (getsizeof(testds_1)) # gives 128

testds_2 = h5f.root.set1.read()
print ("\nFOR: testds_2 = h5f.root.set1.read()")
print (getsizeof(testds_2)) # gives 12000096

x = h5f.root.set1[:500000]['param1']
print ("\nFOR: x = h5f.root.set1[:500000]['param1']")
print(getsizeof(x)) # gives 96

print ("\nFOR: y = h5f.root.set1.cols.param1[:500000]")
y = h5f.root.set1.cols.param1[:500000]
print(getsizeof(y)) # gives 4000096

print ("\nFOR: z = h5f.root.set1.read(stop=500000,field='param1')")
z = h5f.root.set1.read(stop=500000,field='param1')
print(getsizeof(z)) # also gives 4000096

print ("\nFOR: a = h5f.root.set1.col('param1')")
a = h5f.root.set1.col('param1')
print(getsizeof(a)) # also gives 4000096

h5f.close()

Вывод сверху:

FOR: testds_1 = h5f.root.set1
[('param1', '<f8'), ('param2', '<f8'), ('param3', '<f8')]
(500000,)
128

FOR: testds_2 = h5f.root.set1.read()
12000096

FOR: x = h5f.root.set1[:500000]['param1']
96

FOR: y = h5f.root.set1.cols.param1[:500000]
4000096

FOR: z = h5f.root.set1.read(stop=500000,field='param1')
4000096

FOR: a = h5f.root.set1.col('param1')
4000096
...