Таблица Numpy - расширенный выбор нескольких критериев - PullRequest
5 голосов
/ 19 марта 2011

У меня есть таблица, которая выглядит примерно так:

IDs    Timestamp     Values

124    300.6          1.23
124    350.1         -2.4
309    300.6          10.3
12     123.4          9.00
18     350.1          2.11
309    350.1          8.3

       ...

, и я хотел бы выбрать все строки, которые принадлежат группе идентификаторов.Я знаю, что могу сделать что-то вроде

table[table.IDs == 124]

, чтобы выбрать все строки одного идентификатора, и я мог бы сделать

table[(table.IDs == 124) | (table.IDs == 309)]

, чтобы получить строки двух идентификаторов.Но представьте, у меня есть ~ 100 000 строк с более чем 1000 уникальными идентификаторами (которые отличаются от индексов строк), и я хочу выбрать все строки, которые соответствуют набору из 10 идентификаторов.Интуитивно я хотел бы сделать это:

# id_list: a list of 10 IDs
table[ table.IDs in id_list ]

, но Python отклоняет этот синтаксис.Единственный способ, о котором я могу подумать, - это сделать следующее:

table[ (table.IDs == id_list[0]) |
       (table.IDs == id_list[1]) |
       (table.IDs == id_list[2]) |
       (table.IDs == id_list[3]) |
       (table.IDs == id_list[4]) |
       (table.IDs == id_list[5]) |
       (table.IDs == id_list[6]) |
       (table.IDs == id_list[7]) |
       (table.IDs == id_list[8]) |
       (table.IDs == id_list[9]) ]

, что мне кажется очень не элегантным - слишком много кода и нет гибкости для списков различной длины.Есть ли способ обойти мою проблему, такую ​​как использование списка или функция .any ()?Любая помощь приветствуется.

Ответы [ 2 ]

7 голосов
/ 19 марта 2011

Вы можете сделать это следующим образом:

subset = table[np.array([i in id_list for i in table.IDs])]

Если у вас есть более свежая версия numpy, вы можете использовать функцию in1d, чтобы сделать ее более компактной:

subset = table[np.in1d(table.IDs, id_list)]

См. Также этот вопрос: индексирование numpy recarray на основе пересечения с внешним массивом

0 голосов
/ 19 марта 2011

Вот решение, которое, вероятно, будет профилироваться быстрее, чем любой цикл Python for. Тем не менее, я не думаю, что это будет лучше, чем in1d. Используйте его, только если вы можете позволить себе временный двумерный массив целых чисел ids.size на table.IDs.size. Здесь ids является массивом id_list.

result = table[~np.all(table.IDs[None]-ids[None].T, 0)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...