Saya mencoba menjalankan ruang parameter fungsi 6 parameter untuk mempelajari perilaku numeriknya sebelum mencoba melakukan sesuatu yang rumit dengannya jadi saya mencari cara yang efisien untuk melakukan ini.
Fungsi saya mengambil nilai float yang diberikan array numpy 6-dim sebagai input. Apa yang saya coba lakukan pada awalnya adalah ini:
Pertama, saya membuat fungsi yang mengambil 2 array dan menghasilkan array dengan semua kombinasi nilai dari dua array
from numpy import *
def comb(a,b):
c = []
for i in a:
for j in b:
c.append(r_[i,j])
return c
Lalu saya biasa reduce()
menerapkannya pada m salinan array yang sama:
def combs(a,m):
return reduce(comb,[a]*m)
Dan kemudian saya mengevaluasi fungsi saya seperti ini:
values = combs(np.arange(0,1,0.1),6)
for val in values:
print F(val)
Ini bekerja tetapi waaaay terlalu lambat. Saya tahu ruang parameter sangat besar, tetapi ini seharusnya tidak terlalu lambat. Saya hanya mencicipi 10 6 (sejuta) poin dalam contoh ini dan butuh lebih dari 15 detik hanya untuk membuat array values
.
Apakah Anda tahu cara yang lebih efisien untuk melakukan ini dengan numpy?
Saya bisa memodifikasi cara fungsi F
mengambil argumen itu jika perlu.
sumber
Jawaban:
Dalam versi yang lebih baru
numpy
(> 1.8.x),numpy.meshgrid()
memberikan implementasi yang jauh lebih cepat:solusi @ pv
numpy.meshgrid()
dulu hanya 2D, sekarang sudah bisa ND. Dalam hal ini, 3D:Perhatikan bahwa urutan hasil akhir sedikit berbeda.
sumber
np.stack(np.meshgrid([1, 2, 3], [4, 5], [6, 7]), -1).reshape(-1, 3)
akan memberikan pesanan yang tepatInilah implementasi murni-numpy. Ini sekitar 5 × lebih cepat daripada menggunakan itertools.
sumber
from sklearn.utils.extmath import cartesian
TypeError: slice indices must be integers or None or have an __index__ method
dilemparkan olehcartesian(arrays[1:], out=out[0:m,1:])
itertools.combinations umumnya adalah cara tercepat untuk mendapatkan kombinasi dari wadah Python (jika Anda memang menginginkan kombinasi, yaitu, pengaturan TANPA pengulangan dan tanpa urutan; bukan itu yang tampaknya dilakukan kode Anda, tetapi saya tidak bisa katakan apakah itu karena kode Anda bermasalah atau karena Anda menggunakan terminologi yang salah).
Jika Anda menginginkan sesuatu yang berbeda dari kombinasi mungkin iterator lain di itertools,
product
ataupermutations
, mungkin lebih bermanfaat bagi Anda. Misalnya, sepertinya kode Anda kira-kira sama dengan:Semua iterator ini menghasilkan tupel, bukan daftar atau array numpy, jadi jika F Anda pilih-pilih tentang array yang numpy, Anda harus menerima overhead tambahan untuk membangun atau membersihkan dan mengisi ulang satu di setiap langkah.
sumber
Anda dapat melakukan sesuatu seperti ini
pemberian yang mana
sumber
Implementasi numpy berikut ini harus sekitar. 2x kecepatan jawaban yang diberikan:
sumber
np.indices((n,...,n)).reshape(k,-1).T
akan dilakukan.Sepertinya Anda ingin kisi untuk mengevaluasi fungsi Anda, dalam hal ini Anda dapat menggunakan
numpy.ogrid
(terbuka) ataunumpy.mgrid
(menyempurnakan):sumber
kamu bisa memakai
np.array(itertools.product(a, b))
sumber
Inilah cara lain, menggunakan NumPy murni, tidak ada rekursi, tidak ada pemahaman daftar, dan tidak ada eksplisit untuk loop. Itu sekitar 20% lebih lambat dari jawaban aslinya, dan ini didasarkan pada np.meshgrid.
Sebagai contoh,
memberi
sumber
Untuk implementasi murni produk Cartesian dari array 1D (atau daftar python datar), cukup gunakan
meshgrid()
, putar sumbutranspose()
, dan bentuk ulang ke ouput yang diinginkan:Perhatikan ini memiliki konvensi perubahan sumbu terakhir tercepat ("gaya C" atau "baris-utama").
Jika Anda ingin mengubah sumbu tercepat pertama ("gaya FORTRAN" atau "kolom-utama"), cukup ubah
order
parameterreshape()
seperti ini:reshape((-1, N), order='F')
sumber
Panda
merge
menawarkan solusi cepat dan naif untuk masalah ini:sumber