Apa yang akan menjadi cara tercepat untuk memeriksa apakah array numpy multidimensi memiliki 0 di semua sisi.
Jadi, untuk contoh 2D sederhana, saya punya:
x = np.random.rand(5, 5)
assert np.sum(x[0:, 0]) == 0
assert np.sum(x[0, 0:]) == 0
assert np.sum(x[0:, -1]) == 0
assert np.sum(x[-1, 0:]) == 0
Walaupun ini oke untuk kasus 2D ke kanan, menulis untuk dimensi yang lebih tinggi agak membosankan dan saya bertanya-tanya apakah ada beberapa trik numpy yang pintar yang dapat saya gunakan di sini untuk membuatnya efisien dan juga lebih dapat dipertahankan.
np.all (x[:, 0] == 0)
lebih aman dari jumlah? Tes jumlah itu benar hanya jika semua angka positif.Jawaban:
Inilah cara Anda dapat melakukannya:
np.take
melakukan hal yang sama dengan pengindeksan "mewah".sumber
numpy.take
membuat salinan. Ini dapat menyebabkan kinerjanya lebih buruk daripada kode berdasarkan pada tampilan. (Pengaturan waktu perlu dipastikan - Efisiensi tampilan NumPy terkadang aneh.)len(x.shape)
dapat ditulis lebih sederhana sebagaix.ndim
.all
dari hubungan arus pendek. Anda bisa menghapus tanda kurung untuk menggunakan ekspresi generator, yang memungkinkanall
untuk kembali segera setelah satunumpy.all
panggilan kembaliFalse
.Inilah jawaban yang benar-benar memeriksa bagian-bagian dari array yang Anda minati, dan tidak membuang waktu untuk membuat topeng ukuran seluruh array. Ada loop tingkat Python, tapi pendek, dengan iterasi sebanding dengan jumlah dimensi, bukan ukuran array.
sumber
not (view[0] == 0).all()
tidak setara denganview[0].any()
?view[0].any()
akan bekerja juga. Saya tidak sepenuhnya yakin tentang implikasi efisiensi dari casting dan buffering yang terlibat dalam dua opsi -view[0].any()
secara teoritis dapat diimplementasikan lebih cepat, tetapi saya telah melihat hasil yang aneh sebelumnya, dan saya tidak sepenuhnya memahami buffering yang terlibat.view[0].view(bool).any()
akan menjadi solusi berkecepatan tinggi.argmax
mungkin benar-benar mengalahkanany
tampilan boolean . Hal ini jadi aneh.argmax
atauany
, menggunakan tampilan boolean berarti menangani nol negatif sebagai tidak sama dengan nol biasa.)Saya membentuk kembali array dan kemudian mengulanginya. Sayangnya, jawaban saya mengasumsikan Anda memiliki setidaknya tiga dimensi dan akan error untuk matriks normal, Anda harus menambahkan klausa khusus untuk array berbentuk 1 & 2 dimensi. Selain itu, ini akan lambat sehingga kemungkinan ada solusi yang lebih baik.
Yang akan menghasilkan
Pada dasarnya saya menumpuk semua dimensi di atas satu sama lain dan kemudian melihat melalui mereka untuk memeriksa tepinya.
sumber
mungkin operator ellipsis adalah apa yang Anda cari, yang akan bekerja untuk banyak dimensi:
sumber
Anda dapat menggunakan
slice
dan boolean masking untuk menyelesaikan pekerjaan:Fungsi ini pertama-tama membentuk "inti" dari array ke dalam tuple
s
, dan kemudian membangun topeng yangTrue
hanya menunjukkan untuk titik yang berbatasan. Pengindeksan Boolean kemudian memberikan poin perbatasan.Contoh kerja:
Kemudian,
np.all(borders==0)
akan memberi Anda informasi yang diinginkan.Catatan: ini pecah untuk array satu dimensi, meskipun saya menganggap itu kasus tepi. Anda mungkin lebih baik hanya memeriksa dua poin yang dimaksud di sana
sumber
np.arange(15)
tidak termasuk 15.