Python Pandas: Obtiene el índice de filas cuya columna coincide con cierto valor

Dado un DataFrame con una columna “BoolCol”, queremos encontrar los índices del DataFrame en los que los valores de “BoolCol” == True

Actualmente tengo la forma iterativa de hacerlo, que funciona perfectamente:

for i in range(100,3000): if df.iloc[i]['BoolCol']== True: print i,df.iloc[i]['BoolCol'] 

Pero esta no es la forma correcta de panda de hacerlo. Después de algunas investigaciones, actualmente estoy usando este código:

 df[df['BoolCol'] == True].index.tolist() 

Este me da una lista de índices, pero no coinciden, cuando los verifico haciendo:

 df.iloc[i]['BoolCol'] 

El resultado es realmente falso !!

¿Cuál sería la forma correcta de Pandas para hacer esto?

df.iloc[i] devuelve la fila ith de df . No me refiero a la etiqueta de índice, i es un índice basado en 0.

En contraste, el index atributo devuelve tags de índice reales , no índices de fila numéricos:

 df.index[df['BoolCol'] == True].tolist() 

o equivalente,

 df.index[df['BoolCol']].tolist() 

Puedes ver la diferencia con bastante claridad si juegas con un DataFrame con un índice no predeterminado que no es igual a la posición numérica de la fila:

 df = pd.DataFrame({'BoolCol': [True, False, False, True, True]}, index=[10,20,30,40,50]) In [53]: df Out[53]: BoolCol 10 True 20 False 30 False 40 True 50 True [5 rows x 1 columns] In [54]: df.index[df['BoolCol']].tolist() Out[54]: [10, 40, 50] 

Si quieres usar el índice ,

 In [56]: idx = df.index[df['BoolCol']] In [57]: idx Out[57]: Int64Index([10, 40, 50], dtype='int64') 

entonces puede seleccionar las filas usando loc lugar de iloc :

 In [58]: df.loc[idx] Out[58]: BoolCol 10 True 40 True 50 True [3 rows x 1 columns] 

Tenga en cuenta que loc también puede aceptar matrices booleanas :

 In [55]: df.loc[df['BoolCol']] Out[55]: BoolCol 10 True 40 True 50 True [3 rows x 1 columns] 

Si tiene una matriz booleana, una mask y necesita valores de índice ordinales, puede calcularlos utilizando np.flatnonzero :

 In [110]: np.flatnonzero(df['BoolCol']) Out[112]: array([0, 3, 4]) 

Utilice df.iloc para seleccionar filas por índice ordinal:

 In [113]: df.iloc[np.flatnonzero(df['BoolCol'])] Out[113]: BoolCol 10 True 40 True 50 True 

Se puede hacer usando la función numpy where ():

 import pandas as pd import numpy as np In [716]: df = pd.DataFrame({"gene_name": ['SLC45A1', 'NECAP2', 'CLIC4', 'ADC', 'AGBL4'] , "BoolCol": [False, True, False, True, True] }, index=list("abcde")) In [717]: df Out[717]: BoolCol gene_name a False SLC45A1 b True NECAP2 c False CLIC4 d True ADC e True AGBL4 In [718]: np.where(df["BoolCol"] == True) Out[718]: (array([1, 3, 4]),) In [719]: select_indices = list(np.where(df["BoolCol"] == True)[0]) In [720]: df.iloc[select_indices] Out[720]: BoolCol gene_name b True NECAP2 d True ADC e True AGBL4 

Aunque no siempre necesita un índice para una coincidencia, pero en caso de que necesite:

 In [796]: df.iloc[select_indices].index Out[796]: Index([u'b', u'd', u'e'], dtype='object') In [797]: df.iloc[select_indices].index.tolist() Out[797]: ['b', 'd', 'e'] 

Primero, puede consultar la query cuando la columna de destino es de tipo bool (PS: para saber cómo usarla, verifique el enlace )

 df.query('BoolCol') Out[123]: BoolCol 10 True 40 True 50 True 

Después de filtrar el df original por la columna booleana podemos seleccionar el índice.

 df=df.query('BoolCol') df.index Out[125]: Int64Index([10, 40, 50], dtype='int64') 

También los pandas tienen un valor nonzero , solo seleccionamos la posición de la fila True y usamos para cortar el DataFrame o el index

 df.index[df.BoolCol.nonzero()[0]] Out[128]: Int64Index([10, 40, 50], dtype='int64')