Тот факт, что у вас есть только максимум N=10, это здорово. Это означает, что такие сравнения возможны. Что вам нужно сделать, так это иметь 10 строковых столбцов, где каждый столбец является меткой. Если у вас меньше 10 меток для строки, вы заполняете ее пустыми строками.
Это позволит вам писать эффективные выражения запросов, которые вы можете использовать в командах Table.where() и Table.read_where() [1]. Предположим, столбцы имеют глупые имена 'col0', 'col1' и т. д. Поскольку сравнение строк в numexpr выполняется точно, а собственного типа набора нет, вам нужно явно развернуть сравнение на равенство:
cond = ("col0 == 'blue' | col1 == 'blue' | col2 == 'blue' | col3 == 'blue' | "
"col4 == 'blue' | col5 == 'blue' | col6 == 'blue' | col7 == 'blue' | "
"col8 == 'blue' | col9 == 'blue'")
rows = [row[:] for row in table.where(cond)]
К счастью, строку cond легко создать программно:
cond = " | ".join(["col{0} == 'blue'".format(i) for i in range(10)])
Однако есть еще кое-что, что вы можете сделать. Сравнение строк громоздкое и медленное. Это связано с тем, что все ваши строки должны иметь одинаковый размер, что означает, что размер столбца определяется вашей самой длинной меткой. Это приводит к большому количеству потерянного пространства. Вместо этого у вас должно быть сопоставление с целыми числами ваших меток. Затем вы можете сохранить целые числа, сравнить их очень быстро. Например, используя списковые индексы:
labels = ['', 'blue', 'red', 'yellow', ...]
labels_to_idx = dict(zip(labels, range(len(labels))))
cond = " | ".join(["col{0} == '{1}'".format(i, labels_to_idx['blue'])
for i in range(10)])
rows = [[labels[x] for x in row[:]] for row in table.where(cond)]
Вы даже можете сохранить список меток в PyTables как EArray, чтобы всегда получать один и тот же порядок индексов, а также иметь возможность расширить список разрешенных меток.
Кроме того, поскольку метки будут использоваться повторно, особенно метка пустой строки, я настоятельно рекомендую включить сжатие.
К сожалению, поскольку индексируются столбцы (а не таблицы), вы не можете индексировать эти запросы.
Со сжатием и отображением в/из целых чисел это, вероятно, самое быстрое и самое маленькое, что вы можете получить.
- http://pytables.github.io/usersguide/libref/structured_storage.html?highlight=read_where#tables.Table.read_where
person
Anthony Scopatz
schedule
09.12.2013