Ini adalah pertanyaan yang agak konseptual, tetapi saya berharap saya bisa mendapatkan saran yang bagus tentang ini. Banyak pemrograman yang saya lakukan adalah dengan array ( NumPy ); Saya sering harus mencocokkan item dalam dua atau lebih array yang ukurannya berbeda dan hal pertama yang saya tuju adalah for-loop atau bahkan lebih buruk, nested for-loop. Saya ingin menghindari for-loop sebanyak mungkin, karena mereka lambat (setidaknya dengan Python).
Saya tahu bahwa untuk banyak hal dengan NumPy ada perintah-perintah yang sudah ditentukan sebelumnya yang perlu saya teliti, tetapi apakah Anda (sebagai programmer yang lebih berpengalaman) memiliki proses pemikiran umum yang muncul di benak Anda ketika Anda harus mengulangi sesuatu?
Jadi saya sering memiliki sesuatu seperti ini, yang mengerikan dan saya ingin menghindarinya:
small_array = np.array(["one", "two"])
big_array = np.array(["one", "two", "three", "one"])
for i in range(len(small_array)):
for p in range(len(big_array)):
if small_array[i] == big_array[p]:
print "This item is matched: ", small_array[i]
Saya tahu ada beberapa cara berbeda untuk mencapai hal ini secara khusus, tetapi saya tertarik pada metode berpikir umum, jika ada.
I want to avoid for-loops as much as possible because they are slow (at least in Python).
Sepertinya Anda menyelesaikan masalah yang salah di sini. Jika Anda perlu mengulangi sesuatu, Anda perlu mengulangi sesuatu; Anda akan mendapatkan hit kinerja yang sama tidak peduli konstruk Python mana yang Anda gunakan. Jika kode Anda lambat, itu bukan karena Anda memilikifor
loop; itu karena Anda melakukan pekerjaan yang tidak perlu atau melakukan pekerjaan di sisi Python yang bisa dilakukan di sisi C. Dalam contoh Anda, Anda melakukan pekerjaan ekstra; Anda bisa melakukannya dengan satu putaran, bukan dua.Jawaban:
Ini adalah kesulitan konseptual yang umum ketika belajar menggunakan NumPy secara efektif. Biasanya, pemrosesan data dalam Python paling baik diungkapkan dalam hal iterator , untuk menjaga penggunaan memori rendah, untuk memaksimalkan peluang paralelisme dengan sistem I / O, dan untuk menyediakan penggunaan kembali dan kombinasi bagian-bagian algoritma.
Tapi NumPy membalikkan semua itu: pendekatan terbaik adalah mengekspresikan algoritme sebagai urutan operasi seluruh-array , untuk meminimalkan jumlah waktu yang dihabiskan dalam interpreter Python lambat dan memaksimalkan jumlah waktu yang dihabiskan dalam rutinitas NumPy yang dikompilasi dengan cepat.
Inilah pendekatan umum yang saya ambil:
Simpan versi asli dari fungsi (yang Anda yakini benar) sehingga Anda dapat mengujinya terhadap versi yang ditingkatkan baik untuk kebenaran dan kecepatan.
Bekerja dari dalam ke luar: yaitu, mulailah dengan loop paling dalam dan lihat apakah dapat di-vektor; maka ketika Anda sudah melakukannya, pindah satu tingkat dan lanjutkan.
Luangkan banyak waktu membaca dokumentasi NumPy . Ada banyak fungsi dan operasi di sana dan mereka tidak selalu diberi nama dengan cemerlang, jadi ada baiknya mengenal mereka. Khususnya, jika Anda mendapati diri Anda berpikir, "seandainya ada fungsi yang melakukan ini-dan-itu," maka ada baiknya menghabiskan sepuluh menit mencarinya. Biasanya ada di suatu tempat.
Tidak ada pengganti untuk latihan, jadi saya akan memberi Anda beberapa contoh masalah. Tujuan untuk setiap masalah adalah untuk menulis ulang fungsi sehingga sepenuhnya vektor : yaitu, sehingga terdiri dari urutan operasi NumPy pada seluruh array, tanpa loop Python asli (tidak ada
for
atauwhile
pernyataan, tanpa iterator atau pemahaman).Masalah 1
Masalah 2
Masalah 3
Spoiler di bawah ini. Anda akan mendapatkan banyak hasil terbaik jika Anda sendiri sebelum melihat solusi saya!
jawaban 1
Jawaban 2
Jawaban 3
sumber
list
Untuk membuat segalanya lebih cepat, Anda harus membaca tentang struktur data Anda dan menggunakan yang sesuai.
Untuk ukuran non-sepele dari array kecil dan array besar (misalkan kecil = 100 elemen dan besar = 10.000 elemen) salah satu cara untuk melakukannya adalah dengan mengurutkan array kecil, kemudian beralih di atas array besar dan gunakan pencarian biner untuk menemukan elemen yang cocok dalam array kecil.
Ini akan membuat kompleksitas waktu maksimum, O (N log N) (dan untuk array kecil kecil dan array besar sangat dekat dengan O (N)) di mana solusi loop bersarang Anda adalah O (N ^ 2)
Namun. struktur data apa yang paling efisien sangat tergantung pada masalah yang sebenarnya.
sumber
Anda dapat menggunakan kamus untuk mengoptimalkan kinerja secara signifikan
Ini adalah contoh lain:
sumber