Saya perlu menulis fungsi yang akan mendeteksi jika input berisi setidaknya satu nilai yang non-numerik. Jika nilai non-numerik ditemukan, saya akan memunculkan kesalahan (karena kalkulasi seharusnya hanya mengembalikan nilai numerik). Jumlah dimensi dari larik input tidak diketahui sebelumnya - fungsi harus memberikan nilai yang benar terlepas dari ndim. Sebagai komplikasi tambahan, masukan bisa berupa float tunggal numpy.float64
atau bahkan sesuatu yang aneh seperti array berdimensi nol.
Cara yang jelas untuk mengatasinya adalah dengan menulis fungsi rekursif yang melakukan iterasi pada setiap objek yang dapat diulang dalam larik hingga menemukan non-iterabe. Ini akan menerapkan numpy.isnan()
fungsi di atas setiap objek yang tidak dapat diulang. Jika setidaknya satu nilai non-numerik ditemukan maka fungsi tersebut akan segera mengembalikan False. Sebaliknya, jika semua nilai dalam iterable adalah numerik, pada akhirnya akan mengembalikan True.
Itu berfungsi dengan baik, tetapi cukup lambat dan saya berharap NumPy memiliki cara yang jauh lebih baik untuk melakukannya. Apa alternatif yang lebih cepat dan numpyish?
Ini mockup saya:
def contains_nan( myarray ):
"""
@param myarray : An n-dimensional array or a single float
@type myarray : numpy.ndarray, numpy.array, float
@returns: bool
Returns true if myarray is numeric or only contains numeric values.
Returns false if at least one non-numeric value exists
Not-A-Number is given by the numpy.isnan() function.
"""
return True
contains_nan
terlihat mencurigakan: "Mengembalikan nilai salah jika setidaknya ada satu nilai non-numerik". Saya akan berharapcontains_nan
untuk kembaliTrue
jika array berisi NaN.array(['None', 'None'], dtype=object)
? Haruskah masukan seperti itu hanya menimbulkan pengecualian?float('nan') in x
. Tidak bekerja.Jawaban:
Ini harus lebih cepat daripada iterasi dan akan berfungsi apa pun bentuknya.
Edit: 30x lebih cepat:
Hasil:
Bonus: ini berfungsi dengan baik untuk jenis NumPy non-array:
sumber
float('nan') in x
tidak berfungsi? Saya mencobanya dan python kembali keFalse
manax = [1,2,3,float('nan')]
.numpy.any
genexp hanya mengembalikan genexp; Anda tidak benar-benar melakukan perhitungan yang Anda kira. Jangan pernah memanggilnumpy.any
genexp.np.isfinite
alih-alihnp.isnan
mendeteksi luapan numerik, ketidakstabilan, dll.Jika infinity adalah nilai yang mungkin, saya akan menggunakan numpy.isfinite
Jika nilai di atas terevaluasi menjadi
True
, makamyarray
tidak berisinumpy.nan
,,numpy.inf
atau-numpy.inf
nilai.numpy.nan
akan baik-baik saja dengannumpy.inf
nilai, misalnya:sumber
float('nan') in x
tidak berfungsi? Saya mencobanya dan python kembali keFalse
manax = [1,2,3,float('nan')]
.nan
tidak dianggap sama satu sama lain. Cobafloat('nan') == float('nan')
.Pfft! Mikrodetik! Jangan pernah menyelesaikan masalah dalam mikrodetik yang dapat diselesaikan dalam nanodetik.
Perhatikan bahwa jawaban yang diterima:
Solusi yang lebih baik adalah mengembalikan True segera ketika NAN ditemukan:
dan bekerja untuk n-dimensi:
Bandingkan ini dengan solusi asli numpy:
Metode keluar awal adalah 3 kali lipat atau percepatan besaran (dalam beberapa kasus). Tidak terlalu lusuh untuk anotasi sederhana.
sumber
Dengan numpy 1.3 atau svn Anda bisa melakukan ini
Perlakuan nans dalam perbandingan tidak konsisten di versi sebelumnya.
sumber
float('nan') in x
tidak berfungsi? Saya mencobanya dan python kembali keFalse
manax = [1,2,3,float('nan')]
.float("nan")==float("nan")
giveFalse
(meskipun mungkin seharusnya mengembalikan NAN atau None). Demikian pula keanehan dengan NAN dan boolen NULL benar dalam banyak bahasa, termasuk SQL (di mana NULL = NULL tidak pernah benar).(np.where(np.isnan(A)))[0].shape[0]
akan lebih besar daripada0
jikaA
berisi setidaknya satu elemennan
,A
bisa jadin x m
matriks.Contoh:
sumber