erro sklearn ValueError: A entrada contém NaN, infinito ou um valor muito grande para o tipo (d 'float64')

127

Estou usando o sklearn e estou tendo um problema com a propagação de afinidade. Eu construí uma matriz de entrada e continuo recebendo o seguinte erro.

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

eu corri

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

Eu tentei usar

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

para remover os valores infinitos, mas isso também não funcionou. O que posso fazer para me livrar dos valores infinitos na minha matriz, para poder usar o algoritmo de propagação de afinidade?

Estou usando anaconda e python 2.7.9.

Ethan Waldie
fonte
3
Estou votando para encerrar isso, pois o autor diz que seus dados eram inválidos e, apesar de tudo apontar para ele, ele não validou - os dados equivalentes a um erro de digitação, que é um motivo final.
Marcus Müller
11
Eu tive esse mesmo problema com meu conjunto de dados. Em última análise: um erro de dados, não um bug de aprendizado do scikit. A maioria das respostas abaixo é útil, mas enganosa. Cheque, verifique seus dados, verifique se, quando convertidos float64, são finitos e não nan. A mensagem de erro está correta - esse é quase certamente o problema para quem se encontra aqui.
Owen
1
Para o registro e +1 para @Owen, verifique seus dados de entrada e verifique se não há nenhum valor ausente em nenhuma linha ou grade. Você pode usar a classe Imputer para evitar esse problema.
abautista

Respostas:

103

Isso pode acontecer dentro do scikit e depende do que você está fazendo. Eu recomendo a leitura da documentação para as funções que você está usando. Você pode estar usando um que depende, por exemplo, de sua matriz ser positiva definida e não atender a esse critério.

EDIT : Como eu poderia perder isso:

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

está obviamente errado. Certo seria:

np.any(np.isnan(mat))

e

np.all(np.isfinite(mat))

Você deseja verificar se algum elemento é NaN e não se o valor de retorno da anyfunção é um número ...

Marcus Müller
fonte
4
Os médicos não menciona nada sobre este erro Eu preciso de uma maneira de se livrar dos valores infinitos da minha matriz nupy
Ethan Waldie
3
Como eu disse: eles talvez não estejam na sua matriz de entrada. Eles podem ocorrer na matemática que ocorre entre a entrada e a saída mágica. O ponto é que toda essa matemática depende de certas condições para a entrada. Você deve ler atentamente os documentos para descobrir se suas informações atendem a essas condições.
Marcus Müller
1
@ MarcusMüller, você poderia me indicar o local deste documento onde eles especificam os requisitos da matriz de entrada? Não consigo encontrar os "documentos" aos quais você está se referindo. Obrigado :)
user2253546
38

Recebi a mesma mensagem de erro ao usar o sklearn com pandas . Minha solução é redefinir o índice do meu dataframe dfantes de executar qualquer código do sklearn:

df = df.reset_index()

Encontrei esse problema várias vezes quando removi algumas entradas no meu df, como

df = df[df.label=='desired_one']
Jun Wang
fonte
1
Eu te amo! Esse é um caso raro de eu encontrar a solução certa, apesar de não saber qual é a causa do erro!
Alexandr Kapshuk
Ao fazer o df.reset_index (), ele adicionará o "índice" como uma coluna no df resultante. O que pode não ser útil para todos os cenários. Se o df.reset_index (drop = True) for executado, ele lançará o mesmo erro.
smm 18/09/19
14

Esta é a minha função (com base no presente ) para limpar o conjunto de dados de nan, Infe células faltando (para conjuntos de dados enviesados):

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
fonte
Por que você solta o nan duas vezes? Primeira vez com dropnauma segunda vez ao soltar inf.
luca
Perco alguns dados quando uso essa função para limpar meu conjunto de dados. Alguma suposição por que ???
hackerbuddy
2
Esta é a única resposta que funcionou. Eu tentei 20 outras respostas no SO que não funcionaram. Eu acho que este precisa de mais votos.
Contango 05/07
12

As dimensões da minha matriz de entrada estavam inclinadas, pois minha entrada csv tinha espaços vazios.

Ethan Waldie
fonte
1
Para pandas, eu apenas usei dropna pandas.pydata.org/pandas-docs/stable/generated/…
FindOutIslamNow
10

Esta é a verificação em que falha:

O que diz

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)

Portanto, verifique se você possui valores não NaN em sua entrada. E todos esses valores são realmente valores flutuantes. Nenhum dos valores deve ser Inf também.

tuxdna
fonte
5

Com esta versão do python 3:

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

Observando os detalhes do erro, encontrei as linhas de códigos que causam a falha:

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

Com isso, consegui extrair a maneira correta de testar o que estava acontecendo com meus dados usando o mesmo teste que falhou fornecido pela mensagem de erro: np.isfinite(X)

Depois, com um loop rápido e sujo, pude descobrir que meus dados realmente contêm 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
...

Agora tudo o que tenho a fazer é remover os valores nesses índices.

Raphvanns
fonte
4

Eu tive o erro depois de tentar selecionar um subconjunto de linhas:

df = df.reindex(index=my_index)

Acontece que os my_indexvalores contidos não estavam contidos df.index, então a função reindex inseriu algumas novas linhas e as preencheu nan.

Elias Strehle
fonte
2

Na maioria dos casos, livrar-se de valores infinitos e nulos resolve esse problema.

livrar-se de valores infinitos.

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

livre-se dos valores nulos da maneira que desejar, valor específico como 999, média ou crie sua própria função para atribuir valores ausentes

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

Eu tive o mesmo erro e, no meu caso, X e y eram quadros de dados, então tive que convertê-los em matrizes primeiro:

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

Editar: o X.as_matrix () originalmente sugerido está obsoleto

tekumara
fonte
1

Eu recebi o mesmo erro. trabalhou com df.fillna(-99999, inplace=True)antes de fazer qualquer substituição, substituição etc

Cohen
fonte
4
Esta é uma correção suja. Há uma razão pela qual sua matriz contém nanvalores; você deveria encontrá-lo.
Elias Strehle
os dados poderiam conter nan e isso dá uma maneira de substituí-lo com os dados com os valores que ele / ela considera aceitável
user2867432
0

No meu caso, o problema era que muitas funções do scikit retornam matrizes numpy, que são desprovidas de índice de pandas. Portanto, houve uma incompatibilidade de índice quando usei essas matrizes numpy para criar novos DataFrames e tentei misturá-los com os dados originais.

luca
fonte
0

Remova todos os valores infinitos:

(e substitua por min ou max para essa coluna)

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

experimentar

mat.sum()

Se a soma dos seus dados for infinito (maior que o valor máximo de flutuação que é 3,402823e + 38), você receberá esse erro.

veja a função _assert_all_finite em validation.py no código-fonte do 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
fonte