Pytables замедляется при запросе несовпадающей строки

Я относительно новичок в python и использую pytables для хранения некоторых геномных аннотаций в hdf для более быстрого запроса. Я считаю, что запрос несовпадающей строки в таблице выполняется медленно, но я не знаю, как оптимизировать его для повышения производительности.

Ниже показана одна из таблиц:

In [5]: t
Out[5]: 
/gene/annotation (Table(315202,), fletcher32, blosc(5)) ''
  description := {
  "name": StringCol(itemsize=36, shape=(), dflt='', pos=0),
  "track": StringCol(itemsize=12, shape=(), dflt='', pos=1),
  "etype": StringCol(itemsize=12, shape=(), dflt='', pos=2),
  "event": StringCol(itemsize=36, shape=(), dflt='', pos=3)}
  byteorder := 'irrelevant'
  chunkshape := (1365,)
  autoindex := True
  colindexes := {
    "name": Index(9, full, shuffle, zlib(1)).is_csi=True}

Когда условие соответствует чему-то в таблице, timeit возвращается в микросекундах.

In [6]: timeit [x for x in t.where("name == 'record_exists_in_table'")]
10000 loops, best of 3: 109 µs per loop

Однако, когда я попытался найти несуществующую строку, она находится в миллисекундах.

In [8]: timeit [x for x in t.where("name == 'no_such_record'")]
10 loops, best of 3: 56 ms per loop

Буду очень признателен за любой совет, который укажет мне правильное направление!


person Eric Lim    schedule 19.08.2014    source источник
comment
Хм, это интересно. Не могли бы вы отправить заявку в репозиторий PyTables на github? Если бы вы могли добавить автономный пример, это было бы здорово. Я хотел бы взглянуть на это.   -  person Francesc    schedule 30.08.2014
comment
На всякий случай, если ваша проблема такая же, как у меня: stackoverflow.com/questions/26197622/   -  person user1294122    schedule 05.10.2014
comment
@Francesc Я могу подтвердить эту регрессию в 3.1.1. Переход на версию 3.0.0 решает проблему. Ссылка на соответствующую проблему github с кодом для воспроизведения: github.com/PyTables/PyTables/issues/ 390   -  person ARF    schedule 15.12.2014


Ответы (1)


Я исчерпал свой поиск в Интернете и еще не нашел ничего, что решает проблему. Поэтому я решил использовать SeqIO.index_db() в biopython для создания отдельного индекса, а затем проверить, чтобы убедиться, что условие будет найдено перед выполнением запроса pytable. Не совсем то красивое решение, которое я искал, но это подойдет. Это существенно улучшило производительность при несовпадении условий.

In [6]: timeit [x for x in t.where("name == 'not_found_in_table'")]
10 loops, best of 3: 51.6 ms per loop

In [9]: timeit [x for x in t.search_by_gene('not_found_in_table')]
10000 loops, best of 3: 29.5 µs per loop
person Eric Lim    schedule 21.08.2014