erreur sklearn ValueError: l'entrée contient NaN, l'infini ou une valeur trop grande pour dtype ('float64')

129

J'utilise sklearn et j'ai un problème avec la propagation d'affinité. J'ai construit une matrice d'entrée et j'obtiens toujours l'erreur suivante.

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

j'ai couru

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

J'ai essayé d'utiliser

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

pour supprimer les valeurs infinies mais cela n'a pas fonctionné non plus. Que puis-je faire pour me débarrasser des valeurs infinies dans ma matrice, afin de pouvoir utiliser l'algorithme de propagation d'affinité?

J'utilise anaconda et python 2.7.9.

Ethan Waldie
la source
3
Je vote pour fermer cela, car l'auteur dit lui-même que ses données n'étaient pas valides et bien que tout l'indiquait, il n'a pas validé - les données équivalant à une faute de frappe, ce qui est une raison de fermeture.
Marcus Müller
11
J'ai eu ce même problème avec mon ensemble de données. En fin de compte: une erreur de données, pas un bug scikit learn. La plupart des réponses ci-dessous sont utiles mais trompeuses. Vérifiez vérifier vérifiez vos données, assurez-vous que lorsqu'elles sont converties, float64elles sont à la fois finies et non nan. Le message d'erreur est approprié - c'est presque certainement le problème pour quiconque se trouve ici.
Owen
1
Pour l'enregistrement et +1 pour @Owen, vérifiez vos données d'entrée et assurez-vous qu'il n'y a aucune valeur manquante dans aucune ligne ou grille. Vous pouvez utiliser la classe Imputer pour éviter ce problème.
abautista

Réponses:

103

Cela peut se produire dans scikit, et cela dépend de ce que vous faites. Je recommande de lire la documentation des fonctions que vous utilisez. Vous pourriez en utiliser un qui dépend par exemple du fait que votre matrice est définie positivement et ne remplit pas ces critères.

EDIT : Comment pourrais-je manquer ça:

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

est manifestement faux. Le droit serait:

np.any(np.isnan(mat))

et

np.all(np.isfinite(mat))

Vous voulez vérifier si l'un des éléments est NaN, et non si la valeur de retour de la anyfonction est un nombre ...

Marcus Müller
la source
4
La documentation ne mentionne rien à propos de cette erreur.J'ai besoin d'un moyen de me débarrasser des valeurs infinies de mon tableau nupy
Ethan Waldie
3
Comme je l'ai dit: ils ne sont peut-être pas dans votre tableau d'entrée. Ils peuvent se produire dans le calcul qui se produit entre l'entrée et la sortie magique. Le fait est que tout ce calcul dépend de certaines conditions pour l'entrée. Vous devez lire attentivement la documentation pour savoir si votre entrée satisfait ces conditions.
Marcus Müller
1
@ MarcusMüller pourriez-vous m'indiquer l'emplacement de ce document où ils spécifient les exigences de la matrice d'entrée? Je n'arrive pas à trouver les "documents" auxquels vous faites référence. Merci :)
user2253546
39

J'ai eu le même message d'erreur lors de l'utilisation de sklearn avec des pandas . Ma solution est de réinitialiser l'index de mon dataframe dfavant d'exécuter un code sklearn:

df = df.reset_index()

J'ai rencontré ce problème plusieurs fois lorsque j'ai supprimé certaines entrées de mon df, telles que

df = df[df.label=='desired_one']
Jun Wang
la source
1
Je t'aime! C'est un exemple rare de moi qui trouve la bonne solution sans savoir quelle est la cause de l'erreur!
Alexandr Kapshuk
En faisant le df.reset_index (), il ajoutera l '"index" en tant que colonne dans le df résultant. Ce qui peut ne pas être utile pour tous les scénarios. Si le df.reset_index (drop = True) est exécuté, il génère la même erreur.
smm
16

Ceci est ma fonction ( en fonction de ce ) pour nettoyer l'ensemble de données nan, Infet les cellules manquantes (pour les ensembles de données asymétriques):

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
la source
Pourquoi laissez-vous tomber le nan deux fois? Première fois avec dropnapuis une deuxième fois lors de la suppression d'inf.
luca
Je perds des données lorsque j'utilise cette fonction pour nettoyer mon ensemble de données. Des suggestions pourquoi ???
hackerbuddy
2
C'est la seule réponse qui a fonctionné. J'ai essayé 20 autres réponses sur SO qui n'ont pas fonctionné. Je pense que celui-ci a besoin de plus de votes positifs.
Contango
12

Les dimensions de mon tableau d'entrée étaient biaisées, car mon csv d'entrée avait des espaces vides.

Ethan Waldie
la source
1
Pour les pandas, je viens d'utiliser dropna pandas.pydata.org/pandas-docs/stable/generated
...
10

C'est le contrôle sur lequel il échoue:

Qui dit

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)

Assurez-vous donc que vous avez des valeurs non NaN dans votre entrée. Et toutes ces valeurs sont en fait des valeurs flottantes. Aucune des valeurs ne doit non plus être Inf.

Tuxdna
la source
5

Avec cette version de python 3:

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

En regardant les détails de l'erreur, j'ai trouvé les lignes de codes à l'origine de l'échec:

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

À partir de là, j'ai pu extraire la bonne façon de tester ce qui se passait avec mes données en utilisant le même test qui échoue donné par le message d'erreur: np.isfinite(X)

Puis avec une boucle rapide et sale, j'ai pu constater que mes données contiennent bien 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
...

Il ne me reste plus qu'à supprimer les valeurs de ces index.

Raphvanns
la source
4

J'ai eu l'erreur après avoir essayé de sélectionner un sous-ensemble de lignes:

df = df.reindex(index=my_index)

Il s'avère qu'il my_indexcontenait des valeurs qui n'étaient pas contenues dans df.index, de sorte que la fonction de réindexation a inséré de nouvelles lignes et les a remplies nan.

Elias Strehle
la source
2

Dans la plupart des cas, la suppression des valeurs infinies et nulles résout ce problème.

se débarrasser des valeurs infinies.

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

supprimez les valeurs nulles comme vous le souhaitez, une valeur spécifique telle que 999, signifie ou créez votre propre fonction pour imputer les valeurs manquantes

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

J'ai eu la même erreur, et dans mon cas, X et y étaient des dataframes, j'ai donc dû d'abord les convertir en matrices:

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

Edit: Le X.as_matrix proposé à l' origine () est désapprouvée

tekumara
la source
1

J'ai eu la même erreur. il a fonctionné avec df.fillna(-99999, inplace=True)avant de faire tout remplacement, substitution, etc.

Cohen
la source
4
C'est une mauvaise solution. Il y a une raison pour laquelle votre tableau contient des nanvaleurs; vous devriez le trouver.
Elias Strehle
les données pourraient contenir nan et cela donne un moyen de les remplacer par des données avec des valeurs qu'il / elle trouve acceptables
user2867432
0

Dans mon cas, le problème était que de nombreuses fonctions scikit renvoient des tableaux numpy, qui sont dépourvus d'index pandas. Il y avait donc une incompatibilité d'index lorsque j'ai utilisé ces tableaux numpy pour créer de nouveaux DataFrames, puis j'ai essayé de les mélanger avec les données d'origine.

Luca
la source
0

Supprimez toutes les valeurs infinies:

(et remplacez par min ou max pour cette colonne)

# 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
la source
-1

essayer

mat.sum()

Si la somme de vos données est infinie (supérieure à la valeur flottante maximale qui est 3.402823e + 38), vous obtiendrez cette erreur.

voir la fonction _assert_all_finite dans validation.py à partir du code source 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
la source