Numpy: ENH: Alternatif untuk `random.shuffle`, dengan argumen `axis`.

Dibuat pada 11 Okt 2014  ·  35Komentar  ·  Sumber: numpy/numpy

Akan lebih baik jika memiliki alternatif untuk numpy.random.shuffle yang menerima argumen axis , dan yang secara independen mengocok irisan satu dimensi. Inilah implementasi yang akan saya panggil disarrange . Ini berhasil, tetapi akan menyenangkan untuk memiliki implementasi C yang lebih efisien.

def disarrange(a, axis=-1):
    """
    Shuffle `a` in-place along the given axis.

    Apply numpy.random.shuffle to the given axis of `a`.
    Each one-dimensional slice is shuffled independently.
    """
    b = a.swapaxes(axis, -1)
    # Shuffle `b` in-place along the last axis.  `b` is a view of `a`,
    # so `a` is shuffled in place, too.
    shp = b.shape[:-1]
    for ndx in np.ndindex(shp):
        np.random.shuffle(b[ndx])
    return

Contoh:

In [156]: a = np.arange(20).reshape(4,5)

In [157]: a
Out[157]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])

In [158]: disarrange(a, axis=-1)

In [159]: a
Out[159]: 
array([[ 2,  0,  4,  3,  1],
       [ 8,  6,  7,  9,  5],
       [11, 14, 13, 10, 12],
       [19, 18, 16, 17, 15]])

In [160]: a = np.arange(20).reshape(4,5)

In [161]: disarrange(a, axis=0)

In [162]: a
Out[162]: 
array([[ 5, 11,  7, 13, 14],
       [ 0,  6,  2,  3,  4],
       [10,  1, 17, 18, 19],
       [15, 16, 12,  8,  9]])

Permintaan ini dimotivasi oleh pertanyaan ini di stackoverflow: http://stackoverflow.com/questions/26310346/quickly-calculate-randomized-3d-numpy-array-from-2d-numpy-array/

01 - Enhancement numpy.random

Komentar yang paling membantu

Ada berita tentang ini? Saya terkejut fungsi ini tidak ada. Untuk saat ini saya menggunakan np.apply_along_axis dengan np.random.permutation sebagai solusinya.

Semua 35 komentar

Tidak mengerti mengapa ini perlu menjadi alternatif -- mengapa tidak menambahkan saja
argumen sumbu untuk diacak? Default ke Tidak Ada, seperti np.sum.

Pada Sabtu, 11 Okt 2014 jam 21:36, Warren Weckesser [email protected]
menulis:

Akan menyenangkan untuk memiliki alternatif untuk numpy.random.shuffle itu
menerima argumen sumbu, dan yang secara independen mengocok
irisan satu dimensi. Inilah implementasi yang saya sebut disarrange.
Ini berhasil, tetapi akan menyenangkan untuk memiliki implementasi C yang lebih efisien.

def disarrange(a, axis=-1):
"""
Acak a di tempat di sepanjang sumbu yang diberikan.

Apply numpy.random.shuffle to the given axis of `a`.
Each one-dimensional slice is shuffled independently.
"""
b = a.swapaxes(axis, -1)
# Shuffle `b` in-place along the last axis.  `b` is a view of `a`,
# so `a` is shuffled in place, too.
shp = b.shape[:-1]
for ndx in np.ndindex(shp):
    np.random.shuffle(b[ndx])
return

Contoh:

Dalam [156]: a = np.arange(20).reshape(4,5)

Dalam [157]: a
Keluar[157]:
larik([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])

Dalam [158]: disarrange(a, axis=-1)

Dalam [159]: a
Keluar[159]:
larik([[ 2, 0, 4, 3, 1],
[ 8, 6, 7, 9, 5],
[11, 14, 13, 10, 12],
[19, 18, 16, 17, 15]])

Dalam [160]: a = np.arange(20).reshape(4,5)

Dalam [161]: disarrange(a, axis=0)

Dalam [162]: a
Keluar[162]:
larik([[ 5, 11, 7, 13, 14],
[ 0, 6, 2, 3, 4],
[10, 1, 17, 18, 19],
[15, 16, 12, 8, 9]])

Permintaan ini dimotivasi oleh pertanyaan ini di stackoverflow:
http://stackoverflow.com/questions/26310346/quickly-calculate-randomized-3d-numpy-array-from-2d-numpy-array/


Balas email ini secara langsung atau lihat di GitHub
https://github.com/numpy/numpy/issues/5173.

Nathaniel J. Smith
Peneliti pascadoktoral - Informatika - Universitas Edinburgh
http://vorpus.org

Perilaku shuffle ini tidak benar-benar seperti axis=None . Ini memperlakukan argumennya sebagai urutan satu dimensi.

In [181]: a = np.arange(20).reshape(4,5)

In [182]: np.random.shuffle(a)

In [183]: a
Out[183]: 
array([[ 0,  1,  2,  3,  4],
       [15, 16, 17, 18, 19],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

Anda dapat menafsirkannya sebagai axis=0 , tetapi fitur yang hilang adalah pengacakan independen dari irisan 1-D.

Untuk larik 2D, Anda dapat mengacak a.T untuk meniru axis=1 , tetapi ini tidak akan membuat Anda mengocok secara independen:

In [184]: a = np.arange(20).reshape(4,5)

In [185]: np.random.shuffle(a.T)

In [186]: a
Out[186]: 
array([[ 4,  1,  0,  3,  2],
       [ 9,  6,  5,  8,  7],
       [14, 11, 10, 13, 12],
       [19, 16, 15, 18, 17]])

Dalam disarrange , saya berharap axis=None bertindak seperti np.random.shuffle(a.flat) .

Akan baik-baik saja jika pengacakan alternatif diimplementasikan dengan menambahkan argumen yang sesuai ke shuffle yang mengontrol perilakunya, tetapi saya tidak memiliki proposal untuk API itu.

Mungkin dua argumen dapat ditambahkan ke shuffle : axis dan independent (atau sesuatu seperti itu). Tanda tangan baru akan menjadi:

def shuffle(a, independent=False, axis=0)

Ketika independent adalah False, ia bertindak seperti shuffle . Ketika Benar, ia bertindak seperti disarrange .

Oh, ugh, saya hanya berasumsi bahwa itu lebih konsisten dengan analog
fungsinya seperti sort :-(. Akan lebih baik jika seperti ini
shuffling-of-slices ditulis seperti idx = arange(...); acak(idx);
multi_dim_array[idx, ...]; tapi gak ada yang nanya :-)

Saya memberi +1 pada versi shuffle yang memiliki konvensi pemanggilan yang cocok
np.sort, meskipun sebagai aturan kita harus memeriksa dengan daftar. Mereka mungkin memiliki
saran tentang masalah penting seperti nama terbaik juga :-)

(Mungkin "berebut"?)

Pada Sabtu, 11 Okt 2014 jam 22:31, Warren Weckesser < [email protected]

menulis:

Perilaku shuffle saat ini tidak benar-benar seperti axis=None. Ini memperlakukan
argumennya sebagai urutan satu dimensi.

Dalam [181]: a = np.arange(20).reshape(4,5)

Dalam [182]: np.random.shuffle(a)

Dalam [183]: a
Keluar[183]:
larik([[ 0, 1, 2, 3, 4],
[15, 16, 17, 18, 19],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])

Anda dapat menafsirkannya sebagai axis=0, tetapi fitur yang hilang adalah
pengocokan independen dari irisan 1-D.

Untuk larik 2-D, Anda dapat mengacak aT untuk meniru axis=1, tetapi ini tidak akan
membuat Anda mengocok independen:

Dalam [184]: a = np.arange(20).reshape(4,5)

Dalam [185]: np.random.shuffle(aT)

Dalam [186]: a
Keluar[186]:
larik([[ 4, 1, 0, 3, 2],
[ 9, 6, 5, 8, 7],
[14, 11, 10, 13, 12],
[19, 16, 15, 18, 17]])

Dalam kekacauan, saya berharap axis=None bertindak seperti
np.random.shuffle(a.flat).

Akan baik-baik saja jika pengocokan alternatif diterapkan dengan menambahkan
argumen yang tepat untuk mengacak yang mengontrol perilakunya, tetapi saya tidak
memiliki proposal untuk API itu.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/numpy/numpy/issues/5173#issuecomment -58765220.

Nathaniel J. Smith
Peneliti pascadoktoral - Informatika - Universitas Edinburgh
http://vorpus.org

Ah, menggambarkan perilaku yang diinginkan sebagai analog dari sort adalah ide yang bagus.

Oh, ugh, saya hanya berasumsi bahwa itu lebih konsisten dengan fungsi analog seperti sort

Saya juga terkejut, dan berdasarkan komentar pada pertanyaan stackoverflow, setidaknya dua pengguna numpy berpengalaman lainnya terkejut. Saya akan memulai diskusi di milis.

Saya kira jika rata-rata pengguna saat ini salah maka itu layak
menyebutkan opsi lain -- kami _bisa_ menambahkan argumen untuk dipilih
dua perilaku, yang dimulai dengan default ke perilaku saat ini,
dan pada titik tertentu ganti default setelah banyak FutureWarning dan berteriak
untuk memperingatkan orang. Tapi itu transisi yang buruk untuk dilakukan...

Pada Sabtu, 11 Okt 2014 jam 23:00, Warren Weckesser < [email protected]

menulis:

Oh, ugh, saya hanya berasumsi bahwa itu lebih konsisten dengan analog
fungsi seperti sort

Saya juga terkejut, dan berdasarkan komentar di stackoverflow
pertanyaan, setidaknya dua pengguna numpy berpengalaman lainnya terkejut. Sakit
memulai diskusi di milis.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/numpy/numpy/issues/5173#issuecomment -58766099.

Nathaniel J. Smith
Peneliti pascadoktoral - Informatika - Universitas Edinburgh
http://vorpus.org

Mereka mungkin memiliki saran tentang isu-isu penting seperti nama terbaik juga.

Kami membutuhkan fungsi bernama Sue.

Hanya ingin memberi +1 pada fitur ini, seperti yang saya harapkan ada, secara analog dengan sort(axis=N). Apakah ada keputusan yang dibuat di milis?

Ini akan sangat berguna!

Saya juga akan menghargai itu!

Menurut https://stackoverflow.com/a/35647011/3401634 , untuk array multi-dimensi X

np.random.shuffle(X)

sama dengan

np.take(X, np.random.permutation(X.shape[0]), axis=0, out=X)

Jadi mengapa tidak menerapkan

np.random.shuffle(X, axis=axis)

sebagai

np.take(X, np.random.permutation(X.shape[axis]), axis=axis, out=X)

dengan default axis=0 ?

Ada berita tentang ini? Saya terkejut fungsi ini tidak ada. Untuk saat ini saya menggunakan np.apply_along_axis dengan np.random.permutation sebagai solusinya.

Bisakah ini ditutup sekarang karena #13829?

(Perhatikan bahwa saat mengerjakan contoh di sini, saya menemukan bug dalam kode acak baru. Berikut ini, saya menggunakan perbaikan yang diusulkan di https://github.com/numpy/numpy/pull/14662, yang telah digabungkan.)

@wkschwartz , perubahan #13829 berguna, tetapi bukan peningkatan yang diminta di sini. Sumbu yang ditambahkan di #13829 masih memperlakukan larik sebagai urutan 1-d yang akan diacak. Argumen sumbu baru memungkinkan pengguna untuk menentukan sumbu mana yang dilihat sebagai sumbu 1-d, tetapi tidak melakukan pengacakan independen di dalam sumbu.

Sebagai contoh,

In [1]: import numpy as np                                                      

In [2]: rng = np.random.default_rng()                                           

In [3]: x = np.arange(20).reshape(2, 10)                                        

In [4]: x                                                                       
Out[4]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])

In [5]: rng.shuffle(x, axis=1)                                                  

In [6]: x                                                                       
Out[6]: 
array([[ 5,  9,  6,  4,  7,  0,  3,  2,  1,  8],
       [15, 19, 16, 14, 17, 10, 13, 12, 11, 18]])

Anda dapat melihat bahwa baris belum diacak secara independen . Kolom telah diatur ulang, tetapi nilai dalam setiap kolom adalah sama.

Perilaku yang diminta dalam masalah ini adalah mengacak secara independen, seperti pada kode disarrange saya berikan di atas:

In [10]: x = np.arange(20).reshape(2, 10)                                       

In [11]: x                                                                      
Out[11]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])

In [12]: disarrange(x, axis=1)                                                  

In [13]: x                                                                      
Out[13]: 
array([[ 4,  3,  7,  8,  0,  6,  5,  2,  9,  1],
       [12, 15, 19, 17, 18, 14, 10, 13, 11, 16]])

Saya ingin mengapung ini lagi, mungkin juga untuk pertemuan hari Rabu. Kami baru saja menambahkan kemampuan dimensi yang lebih tinggi ke choice dan permutation dan dalam 1,18 bahkan argumen sumbu (dengan demikian baru).

Semua ini menggunakan logika shuffle saat ini yaitu shuffle the subarrays along this axis , alih-alih shuffle along (individual) axis yang menurut saya bisa dibilang apa yang seharusnya terjadi. Yaitu mengocok "di atas" alih-alih "bersama" atau di dalam sumbu yang diberikan.

Tapi, di hampir semua kesempatan, axis berarti sepanjang sumbu di NumPy, dengan pengecualian yang diharapkan sangat sedikit, seperti apply_over_axes yang memiliki "over" pada namanya. Jadi saya akan sangat berani dan mengklaim bahwa bahkan mengganti nama argumen menjadi over_axis=0 akan lebih baik untuk menghindari kebingungan! Khusus untuk nomor acak di mana pengacakan yang salah mungkin sangat sulit untuk diperhatikan.

Seperti disebutkan dalam referensi silang github di atas, saya memiliki PR yang sedang dikerjakan di https://github.com/numpy/numpy/pull/15121. Saya mendapat beberapa umpan balik yang baik setelah mengirimkan PR, tetapi saya belum meluangkan waktu untuk mengatasi semua masalah yang diangkat.

@WarrenWeckesser itu keren, yang secara pribadi lebih saya khawatirkan adalah bahwa kami memperluas makna berlebih di API baru dan baru-baru ini.
Dan saya bertanya-tanya apakah kita seharusnya tidak menarik kembali sebagian, misalnya dengan setidaknya mengganti nama argumen axis . Atau bahkan menyingkirkan perilaku multidimensi sepenuhnya lagi untuk saat ini...

Saya mungkin hanya bereaksi berlebihan sekarang, karena saya agak kesal karena saya melewatkan ini atau tidak berpikir sampai akhir sebelumnya ... Tapi jujur ​​saya pikir logika saat ini sangat berbahaya. Sangat mudah untuk kehilangan bahwa itu tidak memberikan yang diharapkan bersama berarti. Dan itu bukan arti yang digunakan np.sort .

@seberg , terima kasih telah menyodok masalah ini. Saya pikir kita masih perlu mencapai konsensus tentang API. Saya akan mencoba memberikan ringkasan singkat dari ide-ide masa lalu di sini. Saya akan mengikuti konvensi Anda menggunakan "lebih" dan "bersama" untuk dua interpretasi axis . Saya tidak tahu apakah kita dapat, pada titik ini, benar-benar membatalkan interpretasi "bersama" yang ada dari axis untuk shuffle dan permutation , tetapi saya pikir banyak orang akan senang jika ternyata kita bisa. :)

Di akhir diskusi milis beberapa tahun yang lalu, saya akhirnya berpikir solusinya adalah tidak mengubah API shuffle dan permutation , dan alih-alih memperkenalkan dua metode baru yang diacak di sepanjang sumbu bukannya di atasnya. Satu metode akan bekerja di tempat, dan yang lain akan mengembalikan salinan. Preferensi saya saat itu adalah untuk nama permute dan permuted , tetapi ada beberapa keberatan dengan nama-nama itu. Dalam PR dari Desember lalu, saya memanggil mereka randomly_permute dan randomly_permuted , tetapi nama-nama itu harus dianggap sebagai placeholder. Sebelum mencoba memutuskan nama-nama itu, kita harus memutuskan apakah menambahkan dua fungsi baru adalah pendekatan yang tepat. Mulai sekarang, untuk singkatnya, saya akan merujuk ke metode baru yang diusulkan sebagai permute dan permuted .

Dengan fungsi baru, kita akan memiliki metode Generator terkait berikut ini:

meaning    operate     return
of axis    in-place     copy
-------    --------  -----------
"over"     shuffle   permutation
"along"    permute   permuted

(Metode yang beroperasi "di atas" sumbu, shuffle dan permutation , sudah ada.)

Alih-alih dua metode baru, disarankan agar kita hanya memiliki satu, dengan parameter yang mengontrol perilaku in-place vs. copy. Dua saran telah diajukan untuk ini:

(a) Tambahkan parameter out . Untuk bekerja di tempat, berikan array input sebagai out . Jika out tidak diberikan, kembalikan salinan yang diacak.
(b) Tambahkan flag boolean seperti copy atau inplace , yang menentukan perilaku yang diinginkan.

Alternatif utama untuk membuat metode baru adalah dengan menambahkan parameter baru ke metode yang ada yang mengubah cara axis diinterpretasikan. Sebelum mencantumkan ini, saya akan mengulangi komentar yang dibuat Robert Kern di utas milis tentang bagaimana argumen tambahan kemungkinan akan digunakan dalam praktik (di sini mengacu independent parameter

Sepertinya saya alasan yang sangat bagus untuk memiliki dua metode alih-alih
satu. Saya tidak dapat membayangkan ketika saya tidak akan menggunakan Benar atau Salah secara literal
untuk ini, jadi itu benar-benar harus dua metode yang berbeda.

( Penyimpangan redaksi : Tak pelak lagi dalam diskusi seperti ini, isu pertumbuhan namespace (dalam hal ini, Generator namespace) muncul (kadang-kadang disebut sebagai "polusi namespace"). semuanya sama, namespace yang lebih kecil lebih baik. Tetapi, seperti kebanyakan keputusan desain API, ada pengorbanan yang harus dipertimbangkan. Jika kita menjaga namespace lebih kecil tetapi membuat metode dengan API yang canggung atau terlalu rumit, kita tidak menang.)

Setelah mengatakan semua itu, berikut adalah dua tambahan pada tanda tangan shuffle yang telah disarankan.

(1) shuffle(x, axis=0, independent=False) : Bendera boolean independent menentukan bagaimana axis diinterpretasikan: False -> "over", True -> "along". (Mungkin ada nama yang lebih baik daripada independent .)
(2) shuffle(x, axis=0, iaxis=???) : Argumen kedua, iaxis , memberikan sumbu untuk perilaku "sepanjang". (Bagaimana ini berinteraksi dengan axis membutuhkan spesifikasi yang jelas. Agaknya memberikan nilai untuk iaxis menyebabkan axis diabaikan.)

Saya pikir saya telah membahas semua berbagai ide API yang muncul. Jika ada yang tahu tentang orang lain, beri tahu kami.

Saya senang dengan peningkatan API di sini. Saya tidak yakin ada banyak alasan untuk menentangnya:

  • Kita mungkin bisa setuju itu berguna
  • Tidak ada cara yang baik untuk mencapainya dengan fitur yang ada
  • menggunakan kwarg untuk total behavior switch tampaknya bukan pola yang normal, saya pikir Rober Kern benar-benar ada di sana.

Saya kira apa yang terjadi di sini adalah bahwa shuffle dan permutation (dan mungkin choice ) dapat dibandingkan dengan operasi pengindeksan (yaitu take ), yang menggunakan arti yang sama untuk axis . Dan alasan mengapa itu terasa agak aneh bagi saya, mungkin adalah kelemahan dari definisi ini yang tidak pernah dapat digeneralisasikan ke ND tidak seperti fungsi sadar-array pada umumnya (bahkan pengindeksan sendiri melakukannya jika Anda menggunakan arr[..., index] . Itu dia menggeneralisasi ke tumpukan array dan melakukan operasi yang sama seperti sebelumnya untuk masing-masing individu).
Perhatikan bahwa take_along_axis memberikan arti "bersama" ND yang dapat digeneralisasikan untuk take ke ND dengan benar (meskipun tampaknya rumit). apply_along_axis dan apply_over_axis adalah tempat saya mendapatkan "over", meskipun saya tidak yakin bahwa "over" adalah kata yang tepat...

Saya menemukan permutation (yang tidak mudah diubah tetapi seharusnya shuffled ) menjadi outlier nyata di sini. Itu adalah shuffle - shuffled , permute - permuted maka saya pikir semuanya mulai terlihat cukup jelas dan masuk akal. Adakah yang mau menambahkan shuffled dan memulai penghentian pada permutation ? permutation juga tidak terlalu konsisten dalam perilakunya dengan itertools.permutations , FWIW.

Saya pikir permutation , permute , permuted adalah rangkap tiga yang membingungkan dari nama yang terdengar mirip dengan perilaku yang berbeda. Akan lebih baik (mungkin dalam jangka panjang) untuk menghindari hal ini.

Meskipun tampaknya sederhana untuk memperluas API yang ada, saya pikir poin @rkern tentang tidak memiliki kata kunci yang secara radikal mengubah perilaku adalah jalan terbaik.

Saya kira untuk in-place vs. not-in-place, kami memiliki alternatif ejaan out= di NumPy. Tapi karena shuffle ada di tempat itu bukan solusi dan shuffle bagus. Bisa untuk permuted (yaitu permuted(arr, out=arr) artinya sama dengan permute(arr) , kecuali – tidak seperti shuffle – ia akan dikonversi menjadi ndarray ).
Bagaimanapun, saya menyukai rencana untuk menghentikan permutation demi shuffled untuk membersihkan namespace baru!

Saya kembali ke masalah ini (dan PR terkait di https://github.com/numpy/numpy/pull/15121).

Kembali ketika saya membuat masalah asli, dan mencoba menjelaskan masalah dengan shuffle API saat ini, ditunjukkan bahwa salah satu cara untuk menjelaskan masalahnya adalah kebanyakan orang akan mengharapkan argumen axis dari shuffle untuk bertindak sama dengan argumen axis dari sort . Analogi dengan sort cukup bagus, jadi mungkin berguna juga untuk melihat bagaimana kita menangani masalah operasi di tempat vs penyalinan untuk penyortiran. Fungsi numpy.sort() menerima argumen seperti array dan mengembalikan salinan yang diurutkan. Untuk penyortiran di tempat, seseorang menggunakan metode ndarray sort() . Karena ini adalah metode pada ndarray yang ada, operasi di tempat menjadi jelas. Selama di gh-15121, argumen dari fungsi di tempat yang secara acak mengubah argumennya harus berupa ndarray, dan bukan seperti array arbitrer. Jika tidak, fungsi akan harus melakukan semua penemuan bentuk yang np.array tidak, dan juga menolak input yang berubah menjadi berubah (misalnya kita tidak dapat melakukan di tempat shuffle [(1, 2, 3, 4), (5, 6, 7, 8)] ).

Ini akan menjadi besar jika kita benar-benar bisa meniru sort API, dengan fungsi yang kembali salinan dikocok, dan ndarray metode yang mengocok di tempat, tapi saya tidak berpikir menambahkan seperti sebuah metode ke kelas ndarray memiliki peluang untuk diterima.

dan ndarray _method_ yang dikocok di tempat, tapi saya rasa menambahkan metode seperti itu ke kelas ndarray memiliki peluang untuk diterima.

Tanpa generator tunggal saya pikir ini tidak mungkin dicapai.

@bashtage menulis

Saya menemukan permutation (yang tidak mudah diubah tetapi seharusnya shuffled ) menjadi outlier nyata di sini. [Jika] adalah shuffle-shuffled , permute-permuted maka saya pikir semuanya mulai terlihat cukup jelas dan masuk akal. Adakah yang mau menambahkan shuffled dan memulai penghentian pada permutation ?

Inilah yang (semacam) diskusi milis berkumpul kembali pada tahun 2014. Berikut ini tautan ke saran Nathaniel: https://mail.python.org/pipermail/numpy-discussion/2014-October/071364.html

scramble[d] miliknya adalah apa yang saya sebut randomly_permute[d] di https://github.com/numpy/numpy/pull/15121.

Jika kita menambahkan shuffled sebagai pengganti permutation , dan memanggil metode baru yang beroperasi sepanjang sumbu permute[d] , tabel fungsi terkait adalah

meaning    operate
of axis    in-place   return copy
-------    ---------  -----------
"over"     shuffle    shuffled
"along"    permute    permuted

yang memiliki konsistensi yang bagus. Dalam versi API ini, tidak ada metode yang memiliki parameter out .

Di https://github.com/numpy/numpy/pull/15121 , saya baru-baru ini menambahkan metode lain, dengan nama sementara yang canggung dan jelas permuted_with_out yang menunjukkan bagaimana argumen out mungkin digunakan. Jika kita menggunakan parameter out , dan tetap menggunakan nama metode yang ada shuffle dan permutation , tabelnya akan terlihat seperti

meaning    operate
of axis    in-place                           return copy
-------    ---------------------------------  --------------------
"over"     shuffle(x, axis)                   permutation(x, axis)
"along"    permuted_with_out(x, axis, out=x)  permuted_with_out(x, axis)

Tetapi jika kita akan memperkenalkan parameter out , kita harus konsisten dan menggunakannya di permutation . Dan kami masih dapat mempertimbangkan untuk mengganti permutation dengan shuffled . Dan karena metode shuffled memiliki parameter out , yang memungkinkan operasi di tempat, shuffle menjadi berlebihan dan dapat ditinggalkan bersama dengan permutation . Kemudian, beralih ke nama "bagus" dari shuffled dan permuted , tabelnya adalah

    meaning    operate
    of axis    in-place                  return copy
    -------    ------------------------  -----------------
    "over"     shuffled(x, axis, out=x)  shuffled(x, axis)
    "along"    permuted(x, axis, out=x)  permuted(x, axis)

Perhatikan bahwa parameter out tidak hanya untuk beroperasi di tempat. Ini memungkinkan larik keluaran untuk digunakan kembali, berpotensi menghindari pembuatan larik sementara. Ini adalah keuntungan dari API ini dibandingkan dengan shuffle/shuffled/permute/permuted API, tapi saya tidak yakin seberapa signifikan keuntungan itu sebenarnya. Kerugian dari API ini adalah penghentian dua metode, shuffle dan permutation . Ini bisa menjadi penghentian "lunak" untuk sementara waktu (yaitu tidak menekankan penggunaannya dalam dokumen, tetapi tidak benar-benar menambahkan peringatan penghentian untuk sementara waktu) untuk mengurangi dampak langsung.

Itulah ringkasan saya tentang dua pesaing utama untuk perubahan itu. Kami memiliki versi shuffle/shuffled/permute/permuted , atau versi dengan shuffled/permuted dengan parameter out . Jika, pada tahun 2014, seseorang terjun untuk mengimplementasikan perubahan yang telah dibahas, kita mungkin sudah memiliki versi shuffle/shuffled/permute/permuted . Tetapi versi yang menggunakan out memiliki beberapa keuntungan (kecil? tidak signifikan?): dua nama, bukan empat, dan out berpotensi memungkinkan pengguna untuk memiliki lebih sedikit variabel sementara. Saya akan senang dengan salah satunya.

Apa yang orang pikirkan?

Dari tiga skenario yang Anda daftarkan, secara berurutan, saya akan memberi peringkat 1, 3, dan cukup jauh di belakang 2. 2 permutasi yang melakukan hal-hal yang sangat berbeda tampaknya seperti sumber kebingungan yang besar. Preferensi pribadi saya adalah menghindari penggunaan wajib keluar untuk mengakses fitur; Saya selalu menganggapnya sebagai pilihan kinerja yang masuk akal dalam beberapa skenario. Saya tidak ingin mengajar siswa untuk menggunakan hanya untuk mengakses fitur. Saya juga akan berasumsi bahwa dalam kasus 3 x = shuffled(x, axis, out=x) juga akan return x daripada return None , sehingga saat berada di tempatnya, seseorang mungkin berakhir dengan x muncul 3 kali.

Preferensi pribadi saya adalah menghindari penggunaan wajib keluar untuk mengakses fitur; Saya selalu menganggapnya sebagai pilihan kinerja yang masuk akal dalam beberapa skenario.

Tapi menyeret di tempat _adalah_ pilihan kinerja, bukan?

Tapi menyeret di tempat _adalah_ pilihan kinerja, bukan?

In-place juga bisa menjadi pilihan gaya pengkodean, jika tersedia. Mungkin membingungkan, dan mungkin rawan kesalahan.

Pendapat pribadi saya adalah ketika f(x, out=x) selalu terasa sedikit ajaib karena kadang-kadang digunakan sebagai cara yang sangat tidak jelas untuk mencapai sesuatu dengan cepat. f(x, inplace=True), meskipun tidak terlihat seperti yang lain, tampaknya jauh lebih jelas (terlihat sedikit seperti pola panda lama yang sebagian besar telah dihapus).

Benar, tetapi ini adalah pilihan gaya pengkodean yang di NumPy tampaknya biasanya dieja menggunakan out=... (kecuali jika Anda menggunakan operator atau metode di tempat). Atau mungkin ini adalah pilihan gaya pengkodean yang NumPy tidak coba permudah dalam banyak kasus saat ini...

Saya akui itu sedikit ajaib dan inplace= kwarg mungkin kurang ajaib, tetapi juga tanpa prioritas yang nyata? Dan saya tidak yakin apakah alasan utama tampaknya kurang ajaib adalah bahwa pengocokan di tempat adalah inti dari algoritme di sini. Detail algoritmik seharusnya tidak terlalu menjadi masalah bagi sebagian besar siswa dan pada akhirnya menggunakan out= juga menghemat kira-kira satu salinan+bandwidth memori yang terkait, dan sebanding dengan ufunc. (Cukup adil, juga untuk ufuncs out=input mungkin agak ajaib, tetapi keajaiban umum dan pola yang dikenal – untuk pengguna tingkat lanjut.)

Meskipun mungkin sedikit membosankan untuk ditulis, dan agak kurang cepat untuk dibaca, np.shuffled(x, out=x) tampaknya sangat jelas tentang apa perilakunya. Bagian yang tidak jelas tampaknya hanya dampak kinerja, yang bagi saya tampak seperti masalah yang harus dikhawatirkan oleh pengguna tingkat lanjut.

Sebuah pertanyaan hipotetis bagi mereka yang menganjurkan penggunaan out : jika kami tidak memiliki fungsi yang ada numpy.sort dan ndarray.sort , dan kami menambahkan fungsi pengurutan sekarang, apakah API yang disukai menjadi numpy.sorted(a, axis=-1, kind=None, order=None, out=None) (tanpa perlu menerapkan metode ndarray.sort untuk penyortiran di tempat)?

ndarray.sort dimodelkan setelah list.sort , jadi itu mungkin merupakan pilihan API yang masuk akal. Yang mengatakan, saya akan mendukung np.sort tidak ada, dan np.sorted(..., out=...) sebagai gantinya.

Ya, saya pikir np.sort harus diberi nama np.sorted (sama seperti sorted() python). Karena hanya metode yang memiliki perilaku di tempat, saya tidak melihat banyak masalah.

Saya tidak yakin tentang "tanpa perlu menerapkan metode ndarray.sort ". Saya tidak melihat ada yang salah dengan metode ini (atau perilakunya di tempat). Pertanyaan tentang metode ini hanyalah jika kita merasa cukup penting untuk menyediakan metode yang mudah digunakan.
Saya kira tidak ada yang salah dengan memiliki versi fungsi di tempat. Versi tidak di tempat tampaknya lebih baik bagi pengguna baru dan pola out= cukup umum bagi saya sehingga pengguna tingkat lanjut dilayani dengan cukup baik.

Saya tidak yakin tentang "tanpa perlu menerapkan metode ndarray.sort". Saya tidak melihat ada yang salah dengan metode ini (atau perilakunya di tempat).

Itu adalah bagian dari eksperimen pemikiran API saya. Saya tidak bermaksud menyiratkan bahwa ada yang salah dengan apa yang kita miliki sekarang. Saya baru saja mengatakan bahwa, jika kita memulai dari awal--dan saya akan menambahkan premis hipotetis saya bahwa kita tidak peduli dengan pencocokan API Python untuk daftar--maka API yang lebih disukai untuk penyortiran adalah numpy.sorted(..., out=...) , dan kami tidak membutuhkan yang lain.

Pertanyaan lain, tidak terlalu hipotetis: jika menggunakan out adalah opsi yang lebih disukai di sini, maka, untuk konsistensi API di seluruh NumPy, haruskah kita berencana untuk menambahkan out ke numpy.sort , numpy.partition , numpy.argsort , dan, yah, semua hal lain yang saat ini tidak memilikinya?

Ya, menurut saya menambahkan out= kwarg dengan semantik yang sama seperti untuk ufuncs adalah pilihan yang baik untuk hampir semua fungsi API NumPy. Kurangnya argumen out umumnya merupakan peningkatan yang menunggu untuk dibuat (walaupun, saya kira dalam praktiknya ini mungkin peningkatan kecil dan dalam kasus yang jarang mungkin tidak terlalu banyak menambah kompleksitas kode).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat