Numpy: Permintaan: argmax2d

Dibuat pada 21 Jun 2017  ·  13Komentar  ·  Sumber: numpy/numpy

Akan sangat bagus jika ada fungsi kenyamanan untuk melakukan argmax pada array 2D dan mengembalikan indeks baris dan kolom secara maksimal.

Saya sering menemukan diri saya menggunakan kembali kode berikut

def argmax2d(X):
    n, m = X.shape
    x_ = np.ravel(X)
    k = np.argmax(x_)
    i, j = k // m, k % m
    return i, j

Meskipun sederhana, cukup buram di mana saya harus secara konsisten mencari fungsi ini.
Alangkah baiknya jika ini sudah tersedia di numpy.

Apakah ada keberatan untuk membuka PR di numpy agar fungsi ini tersedia?

Komentar yang paling membantu

Mengapa tidak menggunakan np.unravel_index ?

misalnya

np.unravel_index(X.argmax(), X.shape)

Sebagai bonus, ini berfungsi ketika X memiliki lebih dari 2 dimensi.

Semua 13 komentar

Mengapa tidak menggunakan np.unravel_index ?

misalnya

np.unravel_index(X.argmax(), X.shape)

Sebagai bonus, ini berfungsi ketika X memiliki lebih dari 2 dimensi.

Bukan penggemar argmax2d , tapi saya bisa dibujuk oleh i, j = a.argmax(axis=(0, 1))

@eric-wieser bagaimana Anda mengatakan itu harus berperilaku? Saat ini a.argmax() mengembalikan skalar, dan a.argmax(axis=0) mengembalikan array dengan bentuk dimensi yang tersisa. Saya berharap a.argmax(axis=(0,1)) untuk array 3d mengembalikan array bentuk a.shape[2] .

Selain masalah ini, akan sedikit aneh untuk menggunakan a.argmax(axis=range(n)) dalam kasus umum untuk mendapatkan n -length index tuple alih-alih indeks linier integer default. Mungkin kata kunci baru dapat beralih di antara representasi keluaran?

Kemudian lagi, bagaimana opsi hasil sadar bentuk ini bekerja bersama dengan kata kunci axis sudah ada yang menghasilkan nilai pengembalian non-skalar?

Bagaimana jika salah satu baris dalam array 2D Anda tidak memiliki maksimum (hanya array konstan) - bagaimana argmax dapat melaporkannya?
Sebagai contoh:

# setup the problem
import numpy as np
x=np.arange(10).reshape([2,5])
x[1,3]=2
# x is this:
# [[0, 1, 2, 3, 4],
#  [5, 6, 7, 2, 9]]

# this will behave normally
np.argmax(x==2, axis=1)
# Out: [2,3]

# but this one returns 0 instead of NaN
np.argmax(x==3, axis=1)
# Out: [3,0]
# Expected: [3, nan]

Akan lebih baik untuk memiliki argumen tambahan misalnya untuk membiarkan pengguna mengontrol apa yang harus dilakukan jika tidak ada maksimal yang tersedia: np.argmax(x,axis,no_ind=0) (0 adalah default untuk mempertahankan kompatibilitas ke belakang).

@thoth291 bukankah ini pertanyaan yang lebih umum mengenai perilaku argmax ? Hal yang sama terjadi tanpa argumen kata kunci axis pada larik 1d:

>>> np.argmax([2,2,2])
0

Dan ini adalah perilaku adat dalam kasus ikatan: pilih yang pertama di antara nilai-nilai terikat. Demikian pula bagaimana max dari array itu bukan nan : itu 2. Dan jika Anda memiliki maks, Anda harus memiliki indeks yang sesuai. Atau apakah saya melewatkan poin Anda?

@adeak , sekarang Anda mengatakan itu - Saya mulai berpikir bahwa ini memang pertanyaan yang lebih umum.
Saya setuju bahwa max([2,2,2]) sama dengan 2 .
Tetapi pikirkan tentang argmax([2,2,2]) - menurut definisi dalam dokumentasi numpy ia mengembalikan the indices corresponding to the first occurrence . Ini tampaknya OK dari sudut pandang implementasi - tetapi itu benar-benar hanya sebuah arkaisme dari algoritma dan tidak ada hubungannya dengan apa yang sebenarnya harus terjadi. Secara efektif indeks APAPUN dapat dikembalikan dan harus diperlakukan sebagai benar. Atau dapat dikatakan bahwa argmax ambigu dalam kasus array bernilai konstan.

Itu semua dikatakan, saya lebih suka menghindari keputusan seperti itu sejak awal dan mengembalikan inf untuk memberi sinyal bahwa terserah pengguna untuk memutuskan bagaimana menangani kasus seperti itu.

dan tidak ada hubungannya dengan apa yang sebenarnya terjadi.

Maksud Anda "tidak ada hubungannya dengan definisi abstrak argmax"? Saya yakin berharap bahwa _"algoritma"_ dan _"apa yang sebenarnya terjadi"_ bukan hanya hal yang sama, tetapi juga cocok dengan dokumen.

@adeak : Maaf karena tidak pernah membalas

Kemudian lagi, bagaimana opsi hasil sadar bentuk ini bekerja bersama dengan kata kunci sumbu yang ada yang sudah menghasilkan nilai pengembalian non-skalar?

Saya pikir ada satu cara yang jelas untuk menangani ini. Sebagai contoh:

>>> ret = argmax(np.empty((A, B, C, D, E)), axes=(0, 2))
>>> type(ret)
tuple
>>> len(ret)  # == len(axes)
2
>>> ret[0].shape
(B, D, E)
>>> ret[1].shape
(B, D, e)

Dengan itu dan keepdim, Anda akan mendapatkan arr[argmax(arr, axes, keepdims=True)] == max(arr, keepdims=True) untuk dimensi apa pun, yang menurut saya sangat diinginkan

Dalam pseudocode, saya harapkan:

def argmax(arr, axes, keepdims)
    was_tuple = isinstance(axes, tuple):
    if not was_tuple:
        axes = (axes,)

    shape = np.array(arr.shape)
    axis_mask = np.array([i in axes for i in range(arr.ndim)])
    shape[axis_mask] = 1
    ret = tuple(np.empty(shape) for _ in axes)

    # do the actual work

    if not keepdims:
        ret = tuple(r.reshape(shape[~axis_mask]) for r in ret)

    if not was_tuple:
        return ret[0]

@eric-wieser - tangkapan yang bagus - Saya mengetiknya lebih cepat daripada menerjemahkan dengan benar. Akan berhati-hati nanti. Memperbarui komentar menjadi "harus terjadi" alih-alih "terjadi". Harapan yang membantu, jika tidak - terbuka untuk saran untuk reformulasi.
Intinya adalah bahwa argmax([2,2,2])==0 sama baiknya dengan argmax([2,2,2])==1 atau apa pun dan itu harus dipilih oleh pengguna daripada perpustakaan. Jika tidak, mekanisme fallback harus disediakan dalam bentuk (misalnya) kata kunci tambahan default= atau initial= yang akan menginstruksikan apa yang harus dikembalikan dalam kasus ini.

@thoth291 : karena apa yang Anda diskusikan tidak spesifik untuk _2D_ argmax, saya sarankan Anda membuat masalah baru

@eric-wieser jangan khawatir, terima kasih telah menghubungi saya kembali. Saya pikir saya memahami saran Anda, dan tampaknya tidak ambigu dan praktis. Fakta bahwa tipe argumen axis menentukan apakah nilai yang dikembalikan adalah array atau Tuple array agak mengejutkan bagi saya (terutama axes=0 vs axes=[0] ), tapi saya yakin ada banyak contoh yang ada untuk perilaku yang sama (juga, kepraktisan mengalahkan kemurnian).

~Hanya untuk memastikan: dalam contoh Anda jika axes=(0,2) maka bentuk yang dikembalikan harus (B,D,E) , bukan?

Hanya untuk memastikan

Keduanya dikoreksi, tangkapan bagus

Fakta bahwa tipe argumen sumbu menentukan apakah nilai yang dikembalikan adalah array atau Tuple array agak mengejutkan bagi saya

Perhatikan bahwa array yang sebenarnya adalah sama. Saya pikir ini mengenai kepraktisan dan kemurnian - aturannya adalah axis=(a,)res = (arr,) dan axis=ares = arr . Apis tupel kasus khusus ukuran 1 menurut saya ide yang buruk, karena casing khusus itu harus menular ke seluruh tumpukan panggilan

Saya tidak akan pernah berpikir untuk tupel panjang-1 kasus khusus, kedengarannya salah. Saya bertanya-tanya tentang kasus skalar vs tuple. Samar-samar terpikir oleh saya bahwa skalar dan kasus tupel panjang-1 bersesuaian satu sama lain seperti yang Anda sebutkan, tetapi sekarang setelah Anda mengejanya, jelas bahwa skalar -> 1-tupel -> kasing tupel umum adalah generalisasi langsung. Jadi terima kasih, saya sepenuhnya mendukung saran Anda.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat