Saya mencari cara tercepat untuk memeriksa terjadinya NaN ( np.nan
) dalam array NumPy X
. np.isnan(X)
tidak mungkin, karena ia membangun larik bentuk boolean X.shape
, yang berpotensi sangat besar.
Saya mencoba np.nan in X
, tetapi tampaknya tidak berhasil karena np.nan != np.nan
. Apakah ada cara yang cepat dan hemat memori untuk melakukan ini sama sekali?
(Untuk mereka yang bertanya "seberapa besar": Saya tidak tahu. Ini adalah validasi input untuk kode perpustakaan.)
scipy.sparse
matriks NumPy sebagai input.Jawaban:
Solusi Ray bagus. Namun, di komputer saya, ini sekitar 2,5x lebih cepat untuk digunakan
numpy.sum
sebagai penggantinumpy.min
:Berbeda dengan
min
,sum
tidak memerlukan percabangan, yang pada perangkat keras modern cenderung cukup mahal. Ini mungkin alasan mengapasum
lebih cepat.sunting Tes di atas dilakukan dengan satu NaN tepat di tengah-tengah array.
Menarik untuk dicatat bahwa
min
keberadaan NaN lebih lambat dibandingkan saat tidak ada. Tampaknya juga menjadi lebih lambat karena NaN semakin mendekati awal larik. Di sisi lain,sum
throughput tampak konstan terlepas dari apakah ada NaN dan di mana lokasinya:sumber
np.min
lebih cepat ketika array tidak berisi NaN, yang merupakan masukan yang saya harapkan. Tetapi saya telah memutuskan untuk menerima yang ini, karena itu menangkapinf
danneginf
juga.inf
atau-inf
jika masukan berisi keduanya, dan akan bermasalah jika masukan berisi nilai besar tapi terbatas yang meluap saat ditambahkan bersama.np.sum
masih sekitar 30% lebih cepat daripadanp.min
.np.isnan(x).any(0)
sedikit lebih cepat daripadanp.sum
dannp.min
di komputer saya, meskipun mungkin ada beberapa cache yang tidak diinginkan.Saya pikir
np.isnan(np.min(X))
harus melakukan apa yang Anda inginkan.sumber
Bahkan ada jawaban yang diterima, saya ingin menunjukkan yang berikut (dengan Python 2.7.2 dan Numpy 1.6.0 di Vista):
Jadi, cara yang sangat efisien mungkin sangat bergantung pada sistem operasi. Pokoknya
dot(.)
berbasis tampaknya yang paling stabil.sumber
x
berisi nilai besar, dan saya juga ingin memeriksa inf.isfinite(.)
. Saya hanya ingin menunjukkan kesenjangan kinerja yang besar. Terima kasihmin
atausum
, yang berjalan terbatas pada satu inti. Ergo, kesenjangan kinerja itu.Ada dua pendekatan umum di sini:
nan
dan ambilany
.nan
s (sukasum
) dan periksa hasilnya.Meskipun pendekatan pertama tentu yang paling bersih, pengoptimalan yang berat dari beberapa operasi kumulatif (terutama yang dijalankan di BLAS, seperti
dot
) dapat membuatnya cukup cepat. Perhatikan bahwadot
, seperti beberapa operasi BLAS lainnya, multithread dalam kondisi tertentu. Ini menjelaskan perbedaan kecepatan antara mesin yang berbeda.sumber
gunakan .any ()
if numpy.isnan(myarray).any()
numpy.isfinite mungkin lebih baik daripada isnan untuk diperiksa
if not np.isfinite(prop).all()
sumber
Jika Anda merasa nyaman dengan numba memungkinkan untuk membuat korsleting cepat (berhenti segera setelah NaN ditemukan) fungsi:
Jika tidak ada
NaN
fungsi yang sebenarnya mungkin lebih lambat darinp.min
, saya pikir itu karenanp.min
menggunakan multiprocessing untuk array besar:Tetapi jika ada NaN dalam array, terutama jika posisinya berada pada indeks rendah, maka akan lebih cepat:
Hasil serupa dapat dicapai dengan Cython atau ekstensi C, ini sedikit lebih rumit (atau mudah tersedia
bottleneck.anynan
) tetapi pada umumnya melakukan hal yang sama sepertianynan
fungsi saya .sumber
Terkait dengan ini adalah pertanyaan bagaimana menemukan kemunculan pertama NaN. Ini adalah cara tercepat untuk menangani yang saya tahu:
sumber