Saya ingin menerapkan ekspresi berikut dalam Python: mana x dan y adalah array numpy dengan ukuran n , dan k adalah array numpy ukuran n × n . Ukuran n mungkin hingga sekitar 10.000, dan fungsinya adalah bagian dari loop dalam yang akan dievaluasi berkali-kali, jadi kecepatan itu penting.
Idealnya saya ingin menghindari for for loop, walaupun saya kira itu bukan akhir dari dunia jika ada satu. Masalahnya adalah bahwa saya mengalami kesulitan melihat bagaimana melakukannya tanpa memiliki beberapa loop bersarang, dan itu mungkin membuatnya agak lambat.
Adakah yang bisa melihat bagaimana mengekspresikan persamaan di atas menggunakan numpy dengan cara yang efisien, dan lebih disukai juga dapat dibaca? Secara umum, apa cara terbaik untuk mendekati hal semacam ini?
Jawaban:
Inilah solusi Numba. Di komputer saya, versi Numba> 1000x lebih cepat dari versi python tanpa dekorator (untuk matriks 200x200, 'k' dan vektor panjang 200 'a'). Anda juga dapat menggunakan dekorator @autojit yang menambahkan sekitar 10 mikrodetik per panggilan sehingga kode yang sama akan bekerja dengan beberapa tipe.
Pengungkapan: Saya adalah salah satu pengembang Numba.
sumber
Ini awal. Pertama, permintaan maaf saya untuk kesalahan.
Sunting: Tidak, batas atas benar seperti yang disediakan dalam pertanyaan. Saya membiarkannya seperti di sini karena jawaban lain sekarang menggunakan kode yang sama, tetapi perbaikannya sederhana.
Pertama versi berulang:
Saya membuatnya menjadi satu loop dengan irisan numpy:
Lalu saya menulis versi loop dari kode (lebih mudah dibaca) Cython.
Di laptop saya, yang ini sekitar 200x lebih cepat dari versi looped (dan 8x lebih cepat dari versi vektor 1-loop). Saya yakin orang lain bisa berbuat lebih baik.
Saya bermain dengan versi Julia, dan sepertinya (jika saya mengatur waktunya dengan benar) sebanding dengan kode Cython.
sumber
Apa yang Anda inginkan tampaknya menjadi lilitan; Saya pikir cara tercepat untuk mencapainya adalah
numpy.convolve
fungsinya.Anda mungkin harus memperbaiki indeks sesuai dengan kebutuhan Anda, tetapi saya pikir Anda ingin mencoba sesuatu seperti:
sumber