Numpy: Kesalahan penyiaran dengan topeng boolean multi-dimensi

Dibuat pada 3 Apr 2019  ·  3Komentar  ·  Sumber: numpy/numpy

Mencoba mengindeks larik 2D bentuk [N, M] dengan dua topeng boolean 1D, bentuk N dan M, kombinasi tertentu dari Benar dan Salah menyebabkan kesalahan penyiaran (terutama jika salah satu semuanya salah). Saya tidak yakin apakah perilaku ini diharapkan tetapi tampaknya sangat mengejutkan dan tidak diinginkan.

Pada contoh di bawah ini, x[[False, True, True], [True, True, True]] error, sedangkan x[[False, True, True], True] dan x[[False, True, True]] memiliki perilaku yang diharapkan.

Contoh kode reproduksi:

import numpy as np
from itertools import product

x = np.zeros((3,3))
mask_1d = [*product([True, False], repeat=3)]

for row_mask, col_mask in product(mask_1d, mask_1d):
    try:
        x[row_mask, col_mask]
    except IndexError as e:
        print(row_mask, col_mask)
        print(e)

Pesan eror:

     (True, True, True) (True, True, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (True, False, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (False, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (0,) 
(True, True, False) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(True, True, False) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(True, False, True) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(True, False, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(False, True, True) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(False, True, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(False, False, False) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (3,) 
(False, False, False) (True, True, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,) 
(False, False, False) (True, False, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,) 
(False, False, False) (False, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,)

Informasi versi Numpy/Python:

1.16.2 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34) 
[GCC 7.3.0]

Komentar yang paling membantu

Dengan array boolean, kode mengasumsikan Anda mencoba untuk mengindeks satu dimensi atau semua elemen pada saat yang sama - dengan pilihan yang agak sayangnya ditebak dengan cara yang memungkinkan satu True untuk dihapus. Yaitu, itu mengubah row_mask, col_mask menjadi larik boolean (2,3) dan kemudian menemukan bahwa ia tidak dapat mengindeks larik (3,3).

Sebagian dari masalahnya adalah bahwa tupel dan daftar diperlakukan sebagai setara, sesuatu yang kami coba hindari. Akhirnya, Anda akan menangani indeks array boolean dengan memastikan topeng adalah daftar ganda.

Untuk saat ini, saya khawatir satu-satunya solusi adalah melakukan x[row_mask][:, col_mask] .

cc @eric-wieser, yang telah bekerja untuk menghentikan "perlakukan Tuple sebagai daftar" untuk operasi pengindeksan.

ps Paling menjengkelkan saya menemukan perbedaan ini:

x = np.arange(9).reshape(3, 3)
# x[[False, True, True], True]
# array([[3, 4, 5],
#        [6, 7, 8]])
x[[False, True, True], False]
# IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 

Semua 3 komentar

Dengan array boolean, kode mengasumsikan Anda mencoba untuk mengindeks satu dimensi atau semua elemen pada saat yang sama - dengan pilihan yang agak sayangnya ditebak dengan cara yang memungkinkan satu True untuk dihapus. Yaitu, itu mengubah row_mask, col_mask menjadi larik boolean (2,3) dan kemudian menemukan bahwa ia tidak dapat mengindeks larik (3,3).

Sebagian dari masalahnya adalah bahwa tupel dan daftar diperlakukan sebagai setara, sesuatu yang kami coba hindari. Akhirnya, Anda akan menangani indeks array boolean dengan memastikan topeng adalah daftar ganda.

Untuk saat ini, saya khawatir satu-satunya solusi adalah melakukan x[row_mask][:, col_mask] .

cc @eric-wieser, yang telah bekerja untuk menghentikan "perlakukan Tuple sebagai daftar" untuk operasi pengindeksan.

ps Paling menjengkelkan saya menemukan perbedaan ini:

x = np.arange(9).reshape(3, 3)
# x[[False, True, True], True]
# array([[3, 4, 5],
#        [6, 7, 8]])
x[[False, True, True], False]
# IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 

Ya, x[row_mask][:, col_mask] adalah apa yang akhirnya saya lakukan. Terima kasih atas penjelasannya, saya senang itu adalah sesuatu yang sedang diselidiki.

Saya pikir arr[np.ix_(index)] adalah apa yang Anda inginkan/harapkan di sini, atau dengan kata lain pada logika pengindeksan luar seperti dalam NEP 21: https://github.com/numpy/numpy/blob/master/doc/neps /nep-0021-advanced-indexing.rst

Mungkin itu akan diambil suatu saat. NEP juga mengatakan bahwa setidaknya untuk pengindeksan saat ini, beberapa indeks boolean seharusnya tidak digunakan lagi (saya pikir apakah mengizinkan kasus penggunaan khusus ini mungkin masih diperdebatkan – ini konsisten, tetapi mungkin tidak memiliki banyak kasus penggunaan dan cukup membingungkan dalam kasus apapun).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat