¿Cómo eliminar una columna en el dataframe de pandas basado en una condición?

Tengo un dataframe de pandas, con muchos valores NAN .

¿Cómo puedo eliminar columnas de forma que number_of_na_values > 2000 ?

Intenté hacerlo así:

 toRemove = set() naNumbersPerColumn = df.isnull().sum() for i in naNumbersPerColumn.index: if(naNumbersPerColumn[i]>2000): toRemove.add(i) for i in toRemove: df.drop(i, axis=1, inplace=True) 

¿Hay una manera más elegante de hacerlo?

Aquí hay otra alternativa para mantener las columnas que tienen menos o igual al número especificado de nans en cada columna:

 max_number_of_nas = 3000 df = df.loc[:, (df.isnull().sum(axis=0) <= max_number_of_nas)] 

En mis pruebas, esto parece ser un poco más rápido que el método de caída de columnas sugerido por Jianxun Li en los casos que probé:

 np.random.seed(0) df = pd.DataFrame(np.random.randn(10000,5), columns=list('ABCDE')) df[df < 0] = np.nan max_number_of_nans = 5010 %timeit c = df.loc[:, (df.isnull().sum(axis=0) <= max_number_of_nans)] >> 1000 loops, best of 3: 1.76 ms per loop %%timeit c = df.drop(df.columns[df.apply(lambda col: col.isnull().sum() > max_number_of_nans)], axis=1) >> 100 loops, best of 3: 2.04 ms per loop np.random.seed(0) df = pd.DataFrame(np.random.randn(10, 5), columns=list('ABCDE')) df[df < 0] = np.nan max_number_of_nans = 5 %timeit c = df.loc[:, (df.isnull().sum(axis=0) <= max_number_of_nans)] >> 1000 loops, best of 3: 662 µs per loop %%timeit c = df.drop(df.columns[df.apply(lambda col: col.isnull().sum() > max_number_of_nans)], axis=1) >> 1000 loops, best of 3: 1.08 ms per loop 

Misma lógica, pero solo pon todas las cosas en una línea.

 import pandas as pd import numpy as np # artificial data # ==================================== np.random.seed(0) df = pd.DataFrame(np.random.randn(10,5), columns=list('ABCDE')) df[df < 0] = np.nan ABCDE 0 1.7641 0.4002 0.9787 2.2409 1.8676 1 NaN 0.9501 NaN NaN 0.4106 2 0.1440 1.4543 0.7610 0.1217 0.4439 3 0.3337 1.4941 NaN 0.3131 NaN 4 NaN 0.6536 0.8644 NaN 2.2698 5 NaN 0.0458 NaN 1.5328 1.4694 6 0.1549 0.3782 NaN NaN NaN 7 0.1563 1.2303 1.2024 NaN NaN 8 NaN NaN NaN 1.9508 NaN 9 NaN NaN 0.7775 NaN NaN # processing: drop columns with no. of NaN > 3 # ==================================== df.drop(df.columns[df.apply(lambda col: col.isnull().sum() > 3)], axis=1) Out[183]: B 0 0.4002 1 0.9501 2 1.4543 3 1.4941 4 0.6536 5 0.0458 6 0.3782 7 1.2303 8 NaN 9 NaN