sklearn error ValueError: la entrada contiene NaN, infinito o un valor demasiado grande para dtype ('float64')

129

Estoy usando sklearn y tengo un problema con la propagación de afinidad. He construido una matriz de entrada y sigo recibiendo el siguiente error.

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

he corrido

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

Intenté usar

mat[np.isfinite(mat) == True] = 0

para eliminar los valores infinitos, pero esto tampoco funcionó. ¿Qué puedo hacer para deshacerme de los valores infinitos en mi matriz, de modo que pueda usar el algoritmo de propagación por afinidad?

Estoy usando anaconda y python 2.7.9.

Ethan Waldie
fuente
3
Voy a votar para cerrar esto, ya que el autor dice que sus datos no eran válidos y, aunque todo apuntaba a ello, no los validó: los datos equivalen a un error tipográfico, que es una razón final.
Marcus Müller
11
Tuve este mismo problema con mi conjunto de datos. En última instancia: un error de datos, no un error de aprendizaje de scikit. La mayoría de las respuestas a continuación son útiles pero engañosas. Verifique, verifique, verifique sus datos, asegúrese de que cuando se convierta a float64ellos sea finito y no nan. El mensaje de error es adecuado: es casi seguro que este sea el problema para cualquiera que se encuentre aquí.
Owen
1
Para el registro y +1 para @Owen, verifique sus datos de entrada y asegúrese de que no le falte ningún valor en ninguna fila o cuadrícula. Puede utilizar la clase Imputer para evitar este problema.
abautista

Respuestas:

103

Esto puede suceder dentro de scikit y depende de lo que estés haciendo. Recomiendo leer la documentación de las funciones que está utilizando. Es posible que esté utilizando uno que dependa, por ejemplo, de que su matriz sea positiva definida y no cumpla con ese criterio.

EDITAR : ¿Cómo podría perderme eso?

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

obviamente está mal. Correcto sería:

np.any(np.isnan(mat))

y

np.all(np.isfinite(mat))

Desea verificar si alguno de los elementos es NaN, y no si el valor de retorno de la anyfunción es un número ...

Marcus Müller
fuente
4
Los documentos no mencionan nada sobre este error.Necesito una forma de deshacerme de los valores infinitos de mi matriz nupy
Ethan Waldie
3
Como dije: tal vez no estén en su matriz de entrada. Pueden ocurrir en las matemáticas que ocurren entre la entrada y la salida mágica. El punto es que toda esta matemática depende de ciertas condiciones para la entrada. Debe leer atentamente los documentos para averiguar si su entrada satisface estas condiciones.
Marcus Müller
1
@ MarcusMüller, ¿podría indicarme la ubicación de este documento donde especifican los requisitos de la matriz de entrada? Parece que no puedo encontrar los "documentos" a los que se refiere. Gracias :)
user2253546
39

Recibí el mismo mensaje de error al usar sklearn con pandas . Mi solución es restablecer el índice de mi marco de datos dfantes de ejecutar cualquier código sklearn:

df = df.reset_index()

Encontré este problema muchas veces cuando eliminé algunas entradas en mi df, como

df = df[df.label=='desired_one']
Jun Wang
fuente
1
¡Te quiero! ¡Ese es un caso raro en el que encontré la solución correcta a pesar de no saber cuál es la causa del error!
Alexandr Kapshuk
Al hacer el df.reset_index () agregará el "índice" como una columna en el df resultante. Lo que puede no ser útil para todos los escenarios. Si el df.reset_index (drop = True) se ejecutó, arrojará el mismo error.
smm
16

Este es mi función (sobre la base de este ) para limpiar el conjunto de datos de nan, Infy las células que falta (para conjuntos de datos sesgados):

import pandas as pd

def clean_dataset(df):
    assert isinstance(df, pd.DataFrame), "df needs to be a pd.DataFrame"
    df.dropna(inplace=True)
    indices_to_keep = ~df.isin([np.nan, np.inf, -np.inf]).any(1)
    return df[indices_to_keep].astype(np.float64)
Boern
fuente
¿Por qué dejas caer el nan dos veces? Primera vez y dropnaluego una segunda vez al soltar inf.
luca
Pierdo algunos datos cuando uso esta función para limpiar mi conjunto de datos. ¿Alguna sugerencia por qué ???
hackerbuddy
2
Esta es la única respuesta que funcionó. Probé otras 20 respuestas en SO que no funcionó. Creo que este necesita más votos a favor.
Contango
10

Esta es la verificación en la que falla:

Que dice

def _assert_all_finite(X):
    """Like assert_all_finite, but only for ndarray."""
    X = np.asanyarray(X)
    # First try an O(n) time, O(1) space solution for the common case that
    # everything is finite; fall back to O(n) space np.isfinite to prevent
    # false positives from overflow in sum method.
    if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum())
            and not np.isfinite(X).all()):
        raise ValueError("Input contains NaN, infinity"
                         " or a value too large for %r." % X.dtype)

Así que asegúrese de tener valores que no sean NaN en su entrada. Y todos esos valores son en realidad valores flotantes. Ninguno de los valores debe ser Inf tampoco.

tuxdna
fuente
5

Con esta versión de python 3:

/opt/anaconda3/bin/python --version
Python 3.6.0 :: Anaconda 4.3.0 (64-bit)

Mirando los detalles del error, encontré las líneas de códigos que causan la falla:

/opt/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in _assert_all_finite(X)
     56             and not np.isfinite(X).all()):
     57         raise ValueError("Input contains NaN, infinity"
---> 58                          " or a value too large for %r." % X.dtype)
     59 
     60 

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

A partir de esto, pude extraer la forma correcta de probar lo que estaba sucediendo con mis datos utilizando la misma prueba que falla dada por el mensaje de error: np.isfinite(X)

Luego, con un ciclo rápido y sucio, pude encontrar que mis datos realmente contienen nans:

print(p[:,0].shape)
index = 0
for i in p[:,0]:
    if not np.isfinite(i):
        print(index, i)
    index +=1

(367340,)
4454 nan
6940 nan
10868 nan
12753 nan
14855 nan
15678 nan
24954 nan
30251 nan
31108 nan
51455 nan
59055 nan
...

Ahora todo lo que tengo que hacer es eliminar los valores en estos índices.

Raphvanns
fuente
4

Tuve el error después de intentar seleccionar un subconjunto de filas:

df = df.reindex(index=my_index)

Resulta que my_indexcontenía valores que no estaban contenidos df.index, por lo que la función reindexar insertó algunas filas nuevas y las llenó nan.

Elias Strehle
fuente
2

En la mayoría de los casos, deshacerse de valores infinitos y nulos resuelve este problema.

deshacerse de los valores infinitos.

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

deshacerse de los valores nulos de la forma que desee, un valor específico como 999, media, o crear su propia función para imputar los valores faltantes

df.fillna(999, inplace=True)
Natheer Alabsi
fuente
2

Tuve el mismo error, y en mi caso, X e y eran marcos de datos, así que primero tuve que convertirlos en matrices:

X = X.values.astype(np.float)
y = y.values.astype(np.float)

Editar: El X.as_matrix sugerido originalmente () es Desaprobados

tekumara
fuente
1

Tengo el mismo error. funcionó df.fillna(-99999, inplace=True)antes de hacer cualquier reemplazo, sustitución, etc.

Cohen
fuente
4
Esta es una solución sucia. Hay una razón por la que su matriz contiene nanvalores; deberías encontrarlo.
Elias Strehle
los datos podrían contener nan y esto da una manera de reemplazarlos con datos con valores que él / ella encuentre aceptables
user2867432
0

En mi caso, el problema fue que muchas funciones scikit devuelven matrices numpy, que carecen de índice de pandas. Entonces, hubo una falta de coincidencia de índice cuando usé esas matrices numpy para construir nuevos DataFrames y luego intenté mezclarlos con los datos originales.

luca
fuente
0

Eliminar todos los valores infinitos:

(y reemplace con mínimo o máximo para esa columna)

# find min and max values for each column, ignoring nan, -inf, and inf
mins = [np.nanmin(matrix[:, i][matrix[:, i] != -np.inf]) for i in range(matrix.shape[1])]
maxs = [np.nanmax(matrix[:, i][matrix[:, i] != np.inf]) for i in range(matrix.shape[1])]

# go through matrix one column at a time and replace  + and -infinity 
# with the max or min for that column
for i in range(log_train_arr.shape[1]):
    matrix[:, i][matrix[:, i] == -np.inf] = mins[i]
    matrix[:, i][matrix[:, i] == np.inf] = maxs[i]
Renel Chesak
fuente
-1

tratar

mat.sum()

Si la suma de sus datos es infinita (mayor que el valor flotante máximo que es 3.402823e + 38) obtendrá ese error.

vea la función _assert_all_finite en validation.py desde el código fuente de scikit:

if is_float and np.isfinite(X.sum()):
    pass
elif is_float:
    msg_err = "Input contains {} or a value too large for {!r}."
    if (allow_nan and np.isinf(X).any() or
            not allow_nan and not np.isfinite(X).all()):
        type_err = 'infinity' if allow_nan else 'NaN, infinity'
        # print(X.sum())
        raise ValueError(msg_err.format(type_err, X.dtype))
Rick Hill
fuente