errore di sklearn ValueError: l'input contiene NaN, infinity o un valore troppo grande per dtype ('float64')


129

Sto usando sklearn e ho un problema con la propagazione dell'affinità. Ho costruito una matrice di input e continuo a ricevere il seguente errore.

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

Ho corso

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

Ho provato a usare

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

per rimuovere i valori infiniti ma anche questo non ha funzionato. Cosa posso fare per eliminare i valori infiniti nella mia matrice, in modo da poter utilizzare l'algoritmo di propagazione dell'affinità?

Sto usando anaconda e python 2.7.9.


3
Voto per chiudere questo, poiché l'autore stesso afferma che i suoi dati non erano validi e sebbene tutto lo indicasse, non ha convalidato - i dati equivalgono a un errore di battitura, che è una ragione conclusiva.
Marcus Müller

11
Ho avuto lo stesso problema con il mio set di dati. In definitiva: un errore di dati, non un bug di apprendimento di scikit. La maggior parte delle risposte seguenti sono utili ma fuorvianti. Controlla controlla controlla i tuoi dati, assicurati che quando convertiti in float64esso sia finito e non nan. Il messaggio di errore è appropriato: questo è quasi certamente il problema per chiunque si trovi qui.
Owen

1
Per la cronaca e +1 per @Owen, controlla i tuoi dati di input e assicurati di non avere alcun valore mancante in nessuna riga o griglia. È possibile utilizzare la classe Imputer per evitare questo problema.
abautista

Risposte:


103

Questo potrebbe accadere all'interno di scikit e dipende da cosa stai facendo. Consiglio di leggere la documentazione per le funzioni che stai utilizzando. Potresti usarne uno che dipende, ad esempio, dal fatto che la tua matrice sia definita positiva e non soddisfi tali criteri.

EDIT : come potrei perderlo:

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

è ovviamente sbagliato. Giusto sarebbe:

np.any(np.isnan(mat))

e

np.all(np.isfinite(mat))

Vuoi controllare se uno qualsiasi degli elementi è NaN e non se il valore restituito dalla anyfunzione è un numero ...


4
I documenti non menzionano nulla su questo errore, ho bisogno di un modo per sbarazzarmi dei valori infiniti dal mio array nupy
Ethan Waldie

3
Come ho detto: forse non sono nel tuo array di input. Potrebbero verificarsi nella matematica che accade tra input e output magico. Il punto è che tutta questa matematica dipende da determinate condizioni per l'input. Devi leggere attentamente i documenti per scoprire se il tuo input soddisfa queste condizioni.
Marcus Müller

1
@ MarcusMüller potresti indicarmi la posizione di questo documento in cui specificano i requisiti della matrice di input? Non riesco a trovare i "documenti" a cui ti riferisci. Grazie :)
user2253546

39

Ho ricevuto lo stesso messaggio di errore durante l'utilizzo di sklearn con i panda . La mia soluzione è ripristinare l'indice del mio dataframe dfprima di eseguire qualsiasi codice sklearn:

df = df.reset_index()

Ho riscontrato questo problema molte volte quando ho rimosso alcune voci nel mio df, ad esempio

df = df[df.label=='desired_one']

1
Ti amo! È un raro caso in cui trovo la soluzione giusta nonostante non sappia qual è la causa dell'errore!
Alexandr Kapshuk

Facendo df.reset_index () aggiungerà "index" come colonna nel df risultante. Che potrebbe non essere utile per tutti gli scenari. Se df.reset_index (drop = True) è stato eseguito, verrà generato lo stesso errore.
smm

16

Questa è la mia funzione (sulla base di questo ) per pulire il set di dati di nan, Infe le cellule mancante (per insiemi di dati sghembi):

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)

Perché lasci cadere il nonno due volte? Prima volta e dropnapoi una seconda volta quando si rilascia inf.
luca

Perdo alcuni dati quando utilizzo questa funzione per pulire il mio set di dati. Eventuali supposizioni perché ???
hackerbuddy

2
Questa è l' unica risposta che ha funzionato. Ho provato altre 20 risposte su SO che non hanno funzionato. Penso che questo abbia bisogno di più voti positivi.
Contango


10

Questo è il controllo su cui fallisce:

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

Quindi assicurati di avere valori non NaN nel tuo input. E tutti questi valori sono in realtà valori float. Nessuno dei valori dovrebbe essere Inf.


5

Con questa versione di python 3:

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

Guardando i dettagli dell'errore, ho trovato le righe di codici che causano l'errore:

/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').

Da questo, sono stato in grado di estrarre il modo corretto per testare cosa stava succedendo con i miei dati utilizzando lo stesso test che non riesce dato dal messaggio di errore: np.isfinite(X)

Quindi, con un ciclo veloce e sporco, sono stato in grado di scoprire che i miei dati contengono effettivamente 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
...

Ora tutto quello che devo fare è rimuovere i valori in questi indici.


4

Ho riscontrato l'errore dopo aver provato a selezionare un sottoinsieme di righe:

df = df.reindex(index=my_index)

Risulta che my_indexconteneva valori che non erano contenuti in df.index, quindi la funzione di reindicizzazione ha inserito alcune nuove righe e le ha riempite con nan.


2

Nella maggior parte dei casi l'eliminazione di valori infiniti e nulli risolve questo problema.

sbarazzarsi di valori infiniti.

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

sbarazzarsi di valori nulli nel modo desiderato, valore specifico come 999, media o creare la propria funzione per imputare i valori mancanti

df.fillna(999, inplace=True)

2

Ho avuto lo stesso errore e nel mio caso X e y erano dataframe, quindi ho dovuto convertirli prima in matrici:

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

Modifica: X.as_matrix () originariamente suggerito è deprecato


1

ho ricevuto lo stesso errore. ha funzionato df.fillna(-99999, inplace=True)prima di fare qualsiasi sostituzione, sostituzione, ecc


4
Questa è una soluzione sporca. C'è un motivo per cui il tuo array contiene nanvalori; dovresti trovarlo.
Elias Strehle

i dati potrebbero contenere nan e questo dà un modo per sostituirli con dati con valori che lui / lei trova accettabili
user2867432

0

Nel mio caso il problema era che molte funzioni di scikit restituiscono array numpy, che sono privi di indice panda. Quindi c'è stata una mancata corrispondenza dell'indice quando ho usato quegli array numpy per costruire nuovi DataFrame e poi ho provato a mescolarli con i dati originali.


0

Rimuovi tutti i valori infiniti:

(e sostituisci con min o max per quella colonna)

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

-1

provare

mat.sum()

Se la somma dei tuoi dati è infinita (maggiore del valore float massimo che è 3.402823e + 38) otterrai quell'errore.

vedere la funzione _assert_all_finite in validation.py dal codice sorgente di 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))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.