Saya memiliki algoritma berikut yang saya coba optimalkan dengan Python:

Saya mendefinisikan tiga matriks logis (X, Y, & Z) sebelumnya. Masing-masing memiliki N kolom. Saya juga mendefinisikan dua angka yang sangat besar N dan A, dan array angka arbitrer yang saya sebut tot_list yang memiliki panjang A. Saya ingin menelusuri X, Y, dan Z, menemukan di mana elemen masing-masing adalah 1, dan kemudian mengubahnya nilai yang sesuai dalam daftar A_list ke float acak. Ketika operasi ini selesai, saya memperbarui tot_list dengan A_list. Di bawah ini adalah kode yang sebenarnya:

for i in range(0,N):
    A_list = np.ones([1,A])
    
    A_list[0][np.where(X[:,i]==1)[0]] = np.random.random()
    A_list[0][np.where(Y[:,i]==1)[0]] = np.random.random()
    A_list[0][np.where(Z[:,i]==1)[0]] = np.random.random()
    
    tot_list = tot_list+A_list

Kode yang diberikan di atas melakukan persis seperti yang saya inginkan, tetapi berjalan sangat lambat. Saya harus berurusan dengan angka raksasa (yaitu, dengan A di urutan 10^6 dan N di urutan 10^2), dan saya harus mengoptimalkan di atas sebanyak mungkin. Saya sudah mencoba mencari cara untuk menyingkirkan for-loop, tetapi saya tidak yakin bagaimana menerapkannya. Setiap saran akan diterima.

0
Joshuah Heath 20 November 2020, 01:19

1 menjawab

Jawaban Terbaik

Ok, tanpa contoh input dan output agak sulit untuk mengetahui masalahnya, tetapi izinkan saya mencoba menjawab dan saya dapat mengeditnya jika tidak benar.

Seperti yang saya lihat, Anda mengulang setiap baris X, Y dan Z dan menemukan setiap elemen yang 1. Anda dapat melakukan ini untuk setiap elemen array tunggal sekaligus dengan hanya melakukan misalnya X == 1.

Anda kemudian menemukan tempat di mana X, Y, Z sama dengan satu dan mengaturnya ke angka acak, jika tidak, Anda menyetelnya ke 1 (dari definisi Anda tentang A_list). Jadi kita dapat menemukan OR dari semua elemen array yang sama dengan 1 mis.

equal_one = (X == 1) | (Y == 1) | (Z == 1)

Maka kita dapat menggunakan versi tiga argumen np.where untuk menetapkan nilai sama dengan 1 ke angka acak dan yang tidak sama dengan 1 ke 1.

out = np.where(equal_one, np.random.random(), 1)

Akhirnya, kami menjumlahkan setiap baris array, sepanjang satu sumbu. Saya pikir dari contoh Anda ini setara dengan

tot_list = out.sum(axis=1)

Menyatukan semuanya

tot_list = np.where(
    (X == 1) | (Y == 1) | (Z == 1),
    np.random.random(),
    1
).sum(axis=1)
1
tomjn 19 November 2020, 23:18