¿Bajando valores infinitos de marcos de datos en pandas?

¿Cuál es la forma más rápida / sencilla de eliminar los valores nan e inf / -inf de un Marco de datos de pandas sin restablecer mode.use_inf_as_null ? Me gustaría poder usar el subset y how argumentos de dropna , excepto con los valores inf considerados perdidos, como:

 df.dropna(subset=["col1", "col2"], how="all", with_inf=True) 

¿es posible? ¿Hay una manera de decirle a dropna que incluya inf en su definición de valores perdidos?

La forma más sencilla sería replace primero las infs por NaN:

 df.replace([np.inf, -np.inf], np.nan) 

y luego usar la dropna :

 df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all") 

Por ejemplo:

 In [11]: df = pd.DataFrame([1, 2, np.inf, -np.inf]) In [12]: df.replace([np.inf, -np.inf], np.nan) Out[12]: 0 0 1 1 2 2 NaN 3 NaN 

El mismo método funcionaría para una serie.

Aquí hay otro método que usa .loc para reemplazar inf con nan en una serie:

 s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan 

Entonces, en respuesta a la pregunta original:

 df = pd.DataFrame(np.ones((3, 3)), columns=list('ABC')) for i in range(3): df.iat[i, i] = np.inf df ABC 0 inf 1.000000 1.000000 1 1.000000 inf 1.000000 2 1.000000 1.000000 inf df.sum() A inf B inf C inf dtype: float64 df.apply(lambda s: s[np.isfinite(s)].dropna()).sum() A 2 B 2 C 2 dtype: float64 

Con el contexto de opciones, esto es posible sin configurar permanentemente use_inf_as_null . Por ejemplo:

 with pd.option_context('mode.use_inf_as_null', True): df = df.dropna(subset=['col1', 'col2'], how='all') 

Por supuesto, también se puede configurar para tratar inf como NaN permanente con pd.set_option('use_inf_as_null', True) .

La solución anterior modificará las informaciones que no están en las columnas de destino. Para remediar eso,

 lst = [np.inf, -np.inf] to_replace = {v: lst for v in ['col1', 'col2']} df.replace(to_replace, np.nan) 

Otra solución sería utilizar el método isin . Úselo para determinar si cada valor es infinito o falta y luego encadene all método para determinar si todos los valores en las filas son infinitos o faltan.

Finalmente, use la negación de ese resultado para seleccionar las filas que no tienen todos los valores infinitos o faltantes a través de la indexación booleana.

 all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns') df[~all_inf_or_nan] 

Puede usar pd.DataFrame.mask con np.isinf . Debe asegurarse primero de que sus series de marcos de datos son de tipo float . Luego usa dropna con tu lógica existente.

 print(df) col1 col2 0 -0.441406 inf 1 -0.321105 -inf 2 -0.412857 2.223047 3 -0.356610 2.513048 df = df.mask(np.isinf(df)) print(df) col1 col2 0 -0.441406 NaN 1 -0.321105 NaN 2 -0.412857 2.223047 3 -0.356610 2.513048 

Uso (rápido y sencillo):

 df = df[np.isfinite(df).all(1)] 

Esta respuesta se basa en la respuesta de DougR en otra pregunta. Aquí un código de ejemplo:

 import pandas as pd import numpy as np df=pd.DataFrame([1,2,3,np.nan,4,np.inf,5,-np.inf,6]) print('Input:\n',df,sep='') df = df[np.isfinite(df).all(1)] print('\nDropped:\n',df,sep='') 

Resultado:

 Input: 0 0 1.0000 1 2.0000 2 3.0000 3 NaN 4 4.0000 5 inf 6 5.0000 7 -inf 8 6.0000 Dropped: 0 0 1.0 1 2.0 2 3.0 4 4.0 6 5.0 8 6.0