sklearn error ValueError: Die Eingabe enthält NaN, unendlich oder einen Wert, der für dtype zu groß ist ('float64').

127

Ich benutze sklearn und habe ein Problem mit der Affinitätsausbreitung. Ich habe eine Eingabematrix erstellt und erhalte immer wieder den folgenden Fehler.

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

ich bin gerannt

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

Ich habe es versucht

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

die unendlichen Werte zu entfernen, aber dies funktionierte auch nicht. Was kann ich tun, um die unendlichen Werte in meiner Matrix zu entfernen, damit ich den Affinitätsausbreitungsalgorithmus verwenden kann?

Ich benutze Anaconda und Python 2.7.9.

Ethan Waldie
quelle
3
Ich stimme dafür, dies zu schließen, da der Autor selbst sagt, dass seine Daten ungültig waren und obwohl alles darauf hinwies, er sie nicht validierte - die Daten, die einem Tippfehler entsprechen, was ein abschließender Grund ist.
Marcus Müller
11
Ich hatte das gleiche Problem mit meinem Datensatz. Letztendlich: ein Datenfehler, kein Scikit-Lernfehler. Die meisten der folgenden Antworten sind hilfreich, aber irreführend. Check check check überprüfe deine Daten, stelle sicher, dass sie bei der Konvertierung float64sowohl endlich als auch nicht endlich sind nan. Die Fehlermeldung ist passend - dies ist mit ziemlicher Sicherheit das Problem für jeden, der sich hier befindet.
Owen
1
Überprüfen Sie für den Datensatz und +1 für @Owen Ihre Eingabedaten und stellen Sie sicher, dass in keiner Zeile oder in keinem Raster ein Wert fehlt. Sie können die Imputer-Klasse verwenden, um dieses Problem zu vermeiden.
Abautista

Antworten:

101

Dies kann in Scikit passieren und hängt davon ab, was Sie tun. Ich empfehle, die Dokumentation zu den von Ihnen verwendeten Funktionen zu lesen. Möglicherweise verwenden Sie eine, die z. B. davon abhängt, dass Ihre Matrix eindeutig positiv ist und diese Kriterien nicht erfüllt.

EDIT : Wie könnte ich das vermissen:

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

ist offensichtlich falsch. Richtig wäre:

np.any(np.isnan(mat))

und

np.all(np.isfinite(mat))

Sie möchten überprüfen, ob eines der Elemente NaN ist und nicht, ob der Rückgabewert der anyFunktion eine Zahl ist ...

Marcus Müller
quelle
4
Die Dokumente erwähnen nichts über diesen Fehler. Ich brauche eine Möglichkeit, die unendlichen Werte aus meinem Nupy-Array zu entfernen
Ethan Waldie
3
Wie gesagt: Sie befinden sich möglicherweise nicht in Ihrem Eingabearray. Sie können in der Mathematik auftreten, die zwischen Eingabe und magischer Ausgabe stattfindet. Der Punkt ist, dass all diese Mathematik von bestimmten Bedingungen für die Eingabe abhängt. Sie müssen die Dokumente sorgfältig lesen, um herauszufinden, ob Ihre Eingabe diese Bedingungen erfüllt.
Marcus Müller
1
@ MarcusMüller Könnten Sie mich auf den Ort dieses Dokuments verweisen, an dem die Anforderungen der Eingabematrix angegeben sind? Ich kann die "Dokumente", auf die Sie sich beziehen, nicht finden. Vielen Dank :)
user2253546
37

Ich habe die gleiche Fehlermeldung erhalten, wenn ich sklearn mit Pandas verwende . Meine Lösung besteht darin, den Index meines Datenrahmens zurückzusetzen, dfbevor Sie sklearn-Code ausführen:

df = df.reset_index()

Ich bin auf dieses Problem oft gestoßen, als ich einige Einträge in meinem entfernt habe df, z

df = df[df.label=='desired_one']
Jun Wang
quelle
1
Ich liebe dich! Das ist ein seltener Fall, in dem ich die richtige Lösung finde, obwohl ich nicht weiß, was die Fehlerursache ist!
Alexandr Kapshuk
Durch Ausführen von df.reset_index () wird der "Index" als Spalte in die resultierende df eingefügt. Was möglicherweise nicht für alle Szenarien nützlich ist. Wenn der df.reset_index (drop = True) ausgeführt wurde, wird derselbe Fehler ausgegeben.
smm
14

Dies ist meine Funktion (basierend auf diesem ) den Datensatz von zu reinigen nan, Infund fehlenden Zellen (für schiefe Datensätze):

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
quelle
Warum lässt du die Nan zweimal fallen? Erstes Mal mit dropnadann ein zweites Mal beim Ablegen von inf.
Luca
Ich verliere einige Daten, wenn ich diese Funktion zum Bereinigen meines Datensatzes verwende. Irgendwelche Vorschläge warum ???
Hackerbuddy
2
Dies ist die einzige Antwort, die funktioniert hat. Ich habe 20 andere Antworten auf SO ausprobiert, die nicht funktionierten. Ich denke, dieser braucht mehr Upvotes.
Contango
10

Dies ist die Prüfung, bei der es fehlschlägt:

Was sagt

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)

Stellen Sie also sicher, dass Ihre Eingabe Nicht-NaN-Werte enthält. Und all diese Werte sind tatsächlich Float-Werte. Keiner der Werte sollte Inf sein.

tuxdna
quelle
5

Mit dieser Version von Python 3:

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

Als ich mir die Details des Fehlers ansah, fand ich die Codezeilen, die den Fehler verursachten:

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

Daraus konnte ich den richtigen Weg extrahieren, um zu testen, was mit meinen Daten vor sich ging, indem ich denselben Test verwendete, der durch die Fehlermeldung fehlschlägt: np.isfinite(X)

Dann konnte ich mit einer schnellen und schmutzigen Schleife feststellen, dass meine Daten tatsächlich Folgendes enthalten 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
...

Jetzt muss ich nur noch die Werte an diesen Indizes entfernen.

Raphvanns
quelle
4

Ich hatte den Fehler, nachdem ich versucht hatte, eine Teilmenge von Zeilen auszuwählen:

df = df.reindex(index=my_index)

Es stellte sich heraus, dass my_indexWerte enthalten waren, die nicht in enthalten df.indexwaren. Daher fügte die Neuindizierungsfunktion einige neue Zeilen ein und füllte sie mit nan.

Elias Strehle
quelle
2

In den meisten Fällen wird dieses Problem gelöst, wenn unendliche und Nullwerte entfernt werden.

unendliche Werte loswerden.

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

Entfernen Sie Nullwerte nach Ihren Wünschen, bestimmte Werte wie 999, Mittelwert, oder erstellen Sie eine eigene Funktion, um fehlende Werte zu unterstellen

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

Ich hatte den gleichen Fehler und in meinem Fall waren X und y Datenrahmen, sodass ich sie zuerst in Matrizen konvertieren musste:

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

Bearbeiten: Die ursprünglich vorgeschlagene X.as_matrix () ist veraltet

Tekumara
quelle
1

Ich habe den gleichen Fehler. Es hat funktioniert, df.fillna(-99999, inplace=True)bevor es ersetzt, ersetzt usw. wurde

Cohen
quelle
4
Dies ist eine schmutzige Lösung. Es gibt einen Grund, warum Ihr Array nanWerte enthält . du solltest es finden.
Elias Strehle
Die Daten könnten Nan enthalten und dies gibt eine Möglichkeit, sie durch Daten mit Werten zu ersetzen, die er / sie für akzeptabel hält
user2867432
0

In meinem Fall bestand das Problem darin, dass viele Scikit-Funktionen numpy Arrays zurückgeben, die keinen Pandas-Index haben. Es gab also eine Indexinkongruenz, als ich diese Numpy-Arrays zum Erstellen neuer DataFrames verwendete und dann versuchte, sie mit den Originaldaten zu mischen.

luca
quelle
0

Entfernen Sie alle unendlichen Werte:

(und durch min oder max für diese Spalte ersetzen)

# 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
quelle
-1

Versuchen

mat.sum()

Wenn die Summe Ihrer Daten unendlich ist (größer als der maximale Gleitkommawert von 3,402823e + 38), wird dieser Fehler angezeigt.

Siehe die Funktion _assert_all_finite in validation.py aus dem Scikit-Quellcode:

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
quelle