sklearn error ValueError: Input berisi NaN, infinity atau nilai terlalu besar untuk dtype ('float64')

129

Saya menggunakan sklearn dan mengalami masalah dengan propagasi afinitas. Saya telah membangun matriks masukan dan saya terus mendapatkan kesalahan berikut.

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

aku harus lari

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

Saya mencoba menggunakan

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

untuk menghapus nilai tak terbatas tetapi ini juga tidak berhasil. Apa yang dapat saya lakukan untuk menghilangkan nilai tak hingga dalam matriks saya, sehingga saya dapat menggunakan algoritme propagasi afinitas?

Saya menggunakan anaconda dan python 2.7.9.

Ethan Waldie
sumber
3
Saya memilih untuk menutup ini, karena penulis mengatakan sendiri bahwa datanya tidak valid dan meskipun semuanya menunjuk ke sana, dia tidak memvalidasi - data tersebut setara dengan kesalahan ketik, yang merupakan alasan penutupan.
Marcus Müller
11
Saya memiliki masalah yang sama dengan kumpulan data saya. Pada akhirnya: kesalahan data, bukan bug scikit learn. Sebagian besar jawaban di bawah berguna tetapi menyesatkan. Periksa, periksa, periksa data Anda, pastikan bahwa ketika dikonversi ke data float64itu terbatas dan tidak nan. Pesan kesalahannya tepat - ini hampir pasti menjadi masalah bagi siapa pun yang menemukan diri mereka di sini.
Owen
1
Sebagai catatan dan +1 untuk @Owen, periksa data masukan Anda dan pastikan Anda tidak memiliki nilai yang hilang di baris atau kisi mana pun. Anda dapat menggunakan kelas Imputer untuk menghindari masalah ini.
abautista

Jawaban:

103

Ini mungkin terjadi di dalam scikit, dan itu tergantung pada apa yang Anda lakukan. Saya sarankan membaca dokumentasi untuk fungsi yang Anda gunakan. Anda mungkin menggunakan salah satu yang bergantung, misalnya pada matriks Anda menjadi pasti positif dan tidak memenuhi kriteria itu.

EDIT : Bagaimana saya bisa merindukan itu:

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

jelas salah. Benar adalah:

np.any(np.isnan(mat))

dan

np.all(np.isfinite(mat))

Anda ingin memeriksa apakah salah satu elemen adalah NaN, dan bukan apakah nilai yang dikembalikan dari anyfungsi tersebut adalah angka ...

Marcus Müller
sumber
4
Dokumen tidak menyebutkan apa pun tentang kesalahan ini.Saya perlu cara untuk menyingkirkan nilai tak terbatas dari array nupy saya
Ethan Waldie
3
Seperti yang saya katakan: Mereka mungkin tidak ada dalam larik masukan Anda. Mereka mungkin terjadi dalam matematika yang terjadi antara masukan dan keluaran magis. Intinya adalah semua matematika ini bergantung pada kondisi tertentu untuk input. Anda harus membaca dokumen dengan cermat untuk mengetahui apakah masukan Anda memenuhi kondisi ini.
Marcus Müller
1
@ MarcusMüller dapatkah Anda mengarahkan saya ke lokasi dokumen ini di mana mereka menentukan persyaratan matriks masukan? Sepertinya saya tidak dapat menemukan "dokumen" yang Anda maksud. Terima kasih :)
user2253546
39

Saya mendapat pesan kesalahan yang sama saat menggunakan sklearn dengan panda . Solusi saya adalah mengatur ulang indeks bingkai data saya dfsebelum menjalankan kode sklearn apa pun:

df = df.reset_index()

Saya mengalami masalah ini berkali-kali ketika saya menghapus beberapa entri di saya df, seperti

df = df[df.label=='desired_one']
Jun Wang
sumber
1
Aku cinta kamu! Itu adalah contoh langka saya menemukan solusi yang tepat meski tidak tahu apa penyebab kesalahannya!
Alexandr Kapshuk
Dengan melakukan df.reset_index () itu akan menambahkan "indeks" sebagai kolom di df yang dihasilkan. Yang mungkin tidak berguna untuk semua skenario. Jika df.reset_index (drop = True) berjalan maka itu akan memunculkan kesalahan yang sama.
smm
16

Ini adalah fungsi saya (berdasarkan ini ) untuk membersihkan dataset dari nan, Inf, dan sel-sel yang hilang (untuk dataset miring):

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
sumber
Mengapa Anda menjatuhkan nan dua kali? Pertama kali dengan dropnakemudian kedua kalinya saat menjatuhkan inf.
luca
Saya kehilangan beberapa data ketika saya menggunakan fungsi ini untuk membersihkan dataset saya. Ada sugetions kenapa ???
hackerbuddy
2
Ini adalah satu - satunya jawaban yang berhasil. Saya mencoba 20 jawaban lain pada SO yang tidak berhasil. Saya pikir yang ini membutuhkan lebih banyak suara positif.
Contango
10

Ini adalah pemeriksaan yang gagal:

Yang mengatakan

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)

Jadi pastikan Anda memiliki nilai non NaN di masukan Anda. Dan semua nilai itu sebenarnya adalah nilai float. Tidak ada nilai yang harus Inf juga.

tuxdna.dll
sumber
5

Dengan versi python 3 ini:

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

Melihat detail kesalahan, saya menemukan baris kode yang menyebabkan kegagalan:

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

Dari sini, saya dapat mengekstrak cara yang benar untuk menguji apa yang terjadi dengan data saya menggunakan tes yang sama yang gagal diberikan oleh pesan kesalahan: np.isfinite(X)

Kemudian dengan putaran cepat dan kotor, saya dapat menemukan bahwa data saya memang berisi 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
...

Sekarang yang harus saya lakukan adalah menghapus nilai pada indeks ini.

Raphvanns
sumber
4

Saya mengalami kesalahan setelah mencoba memilih subset baris:

df = df.reindex(index=my_index)

Ternyata itu my_indexberisi nilai yang tidak terkandung di dalamnya df.index, sehingga fungsi indeks ulang menyisipkan beberapa baris baru dan mengisinya nan.

Elias Strehle
sumber
2

Dalam kebanyakan kasus, menyingkirkan nilai tak terbatas dan nol memecahkan masalah ini.

singkirkan nilai tak terbatas.

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

singkirkan nilai nol sesuka Anda, nilai spesifik seperti 999, mean, atau buat fungsi Anda sendiri untuk menghubungkan nilai yang hilang

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

Saya mengalami kesalahan yang sama, dan dalam kasus saya X dan y adalah kerangka data, jadi saya harus mengonversinya menjadi matriks terlebih dahulu:

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

Sunting: X.as_matrix () yang semula disarankan tidak digunakan lagi

tekumara
sumber
1

saya mendapat kesalahan yang sama. itu bekerja dengan df.fillna(-99999, inplace=True)sebelum melakukan penggantian, penggantian, dll

Cohen
sumber
4
Ini perbaikan kotor. Ada alasan mengapa array Anda berisi nannilai; kamu harus menemukannya.
Elias Strehle
data dapat berisi nan dan ini memberikan cara untuk menggantinya dengan data dengan nilai yang menurutnya dapat diterima
pengguna2867432
0

Dalam kasus saya, masalahnya adalah banyak fungsi scikit mengembalikan array numpy, yang tidak memiliki indeks pandas. Jadi ada ketidakcocokan indeks ketika saya menggunakan array numpy tersebut untuk membangun DataFrames baru dan kemudian saya mencoba mencampurnya dengan data asli.

luca
sumber
0

Hapus semua nilai tak terbatas:

(dan ganti dengan min atau maks untuk kolom itu)

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

mencoba

mat.sum()

Jika jumlah data Anda tidak terbatas (lebih besar dari nilai float maks yaitu 3.402823e + 38) Anda akan mendapatkan kesalahan itu.

lihat fungsi _assert_all_finite di validation.py dari kode sumber 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
sumber