2011-03-19 14 views
5

tengo una tabla que es algo como esto:mesa Numpy - Criterios de selección múltiple avanzada

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 

     ... 

y me gustaría para seleccionar todas las filas que pertenecen a un grupo de ID. Sé que puedo hacer algo como

table[table.IDs == 124] 

para seleccionar todas las filas de un ID, y no pude hacer

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

para obtener filas dos ID. Pero imagine que tengo ~ 100,000 filas con más de 1,000 ID únicos (que son distintos de los índices de filas), y quiero seleccionar todas las filas que coinciden con un conjunto de 10 ID. Intuitivamente me gustaría hacer esto:

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

pero Python rechaza esta sintaxis. La única manera que se me ocurre es hacer lo siguiente:

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]) ] 

que parece muy poco elegante para mí - demasiado código y no hay flexibilidad para diferentes longitudes de las listas. ¿Hay alguna forma de solucionar mi problema, como el uso de listas de comprensión, o la función .any()? Se agradece cualquier ayuda.

Respuesta

7

Puede hacerlo de esta manera:

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

Si usted tiene una versión más reciente de numpy, puede utilizar la función in1d para que sea un poco más compacta:

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

Ver también esta pregunta: numpy recarray indexing based on intersection with external array

+0

'in1d' es claramente el camino a seguir. – Paul

+0

¡Muchas gracias! Esto es exactamente lo que estaba buscando. –

+1

@ Camarada42: ¡De nada! Siempre puede marcar la pregunta como "respondida" para mayor claridad. – joris

0

Aquí hay una solución que probablemente perfil más rápido que cualquier pitón for loop. Sin embargo, no creo que vaya a funcionar mejor que in1d. Úselo solo si puede pagar una matriz de enteros 2D temporal de ids.size por table.IDs.size. Aquí, ids es la matriz numpy de id_list.

result = table[~np.all(table.IDs[None]-ids[None].T, 0)] 
Cuestiones relacionadas