Получить индекс значения в одномерном массиве Pytables - PullRequest
0 голосов
/ 22 октября 2018

Я сейчас пишу код для колледжа, который работает с очень большими объемами данных, используя Pytables с различными матрицами / матрицами, чтобы не переполнять память, и до сих пор он работал хорошо.

Правильнотеперь мне нужно присвоить целочисленный идентификатор (от 0 до любого) ряду различных строк, сохранить назначение и иметь возможность получить соответствующее целое число для определенной строки и наоборот.Конечно, обычные типы не обрезают его, просто слишком много строк, поэтому мне нужно использовать что-то, что работает с файлами, такими как Pytables.

Я думал просто об использовании одномерного массива Pytables EArray (потому что я могу 'не знаю, сколько будет строк), сохраните там строки и пусть индекс для каждого элемента будет назначенным целочисленным идентификатором строки.

Это пример того, что я подумал использовать:

import tables as tb, numpy as np

>>>file = tb.open_file("sample_file.hdf5", mode='w')
>>>sample_array = file.create_earray(file.root, 'data', tb.StringAtom(itemsize=50),
 shape=(0,), expectedrows=10000)
>>>sample_array.append(np.array(["String_value"]))

Таким образом, я могу получить значение String данного целого числа, как в любом обычном массиве

>>>sample_array[0]
b'String_value'

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

>>> sample_array[np.where("String_value") in sample_array]
b'String_value'
>>> sample_array[np.where("String_value")]
array([b'String_value'], dtype='|S50')
>>> np.where("String_value") in sample_array
False

Заранее спасибо!

РЕДАКТИРОВАТЬ:

Забыл обновить, я понял это, работая над чем-то другим ... Лицом к лицу сильно, очень тяжело, это было действительно глупо, но я не мог понять, что случилось часами.

np.where(sample_array[:] == b'String_value')
>>>(array([0]),)

1 Ответ

0 голосов
/ 26 ноября 2018

ОП ответил на свой вопрос выше.Тем не менее, он скрыт под EDIT: , поэтому он неочевиден в результатах поиска (или для обычного читателя).Кроме того, существует другой способ решения проблемы (использование Table вместо Earray ).Это обеспечивает сравнение 2 методов.

Решение OP с Earray (с некоторыми украшениями):

import tables as tb, numpy as np
h5f = tb.open_file("sample_file.hdf5", mode='w')
sample_array = h5f.create_earray(h5f.root, 'data', tb.StringAtom(itemsize=50),
               shape=(0,), expectedrows=10000)
sample_array.append(np.array(['str_val0']))
sample_array.append(np.array(['str_val10']))
sample_array.append(np.array(['str_val20']))
sample_array.append(np.array(['str_val30']))
sample_array.append(np.array(['str_val40']))
print (sample_array[0])
print (sample_array[-1])
print (np.where(sample_array[:] == b'str_val0'))
print (np.where(sample_array[:] == b'str_val40'))
print ('\n')

h5f.close()

Вывод выглядит так:

b'str_val0'
b'str_val40'
(array([0], dtype=int64),)
(array([4], dtype=int64),)

MyПодход с таблицей:
Мне нравятся таблицы в Pytables.Они удобны тем, что имеют несколько встроенных методов поиска и итерации (в этом случае с помощью .get_where_list (); есть много других).В этом примере показано создание таблицы из np.recarray (для определения полей / столбцов используется dtype, а для заполнения таблицы - данные).Дополнительные строки данных добавляются позже с помощью метода .append ().

import tables as tb, numpy as np
h5f = tb.open_file("sample_file.hdf5", mode='w')

simple_recarray = np.recarray((4,),dtype=[('tstr','S50')])
simple_recarray['tstr'][0] = 'str_val1'
simple_recarray['tstr'][1] = 'str_val2'
simple_recarray['tstr'][2] = 'str_val10'
simple_recarray['tstr'][3] = 'str_val20'

simple_table = h5f.create_table(h5f.root, 'table_data', simple_recarray, 'Simple dataset')

print (simple_table.get_where_list("tstr == b'str_val1'"))
print (simple_table.get_where_list("tstr == b'str_val20'"))

simple_table.append([('str_val30',), ('str_val31',)])

print (simple_table.get_where_list("tstr == b'str_val31'"))

h5f.close()

Вывод выглядит следующим образом (немного разные строки b / c не сохраняются в массивах):

[0]
[3]
[5]
...