Numpy: الطلب: argmax2d

تم إنشاؤها على ٢١ يونيو ٢٠١٧  ·  13تعليقات  ·  مصدر: numpy/numpy

سيكون من الرائع حقًا إذا كانت هناك وظيفة ملائمة لإجراء argmax على صفيف ثنائي الأبعاد وإرجاع فهارس الصفوف والأعمدة من الحد الأقصى.

غالبًا ما أجد نفسي أعيد استخدام الكود التالي

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

على الرغم من أنها بسيطة ، إلا أنها غير شفافة بدرجة كافية حيث يتعين علي البحث باستمرار عن هذه الوظيفة.
سيكون لطيفًا إذا كان هذا متاحًا بالفعل في numpy.

هل ستكون هناك أي اعتراضات على فتح العلاقات العامة في numpy لتوفر هذه الوظيفة بسهولة؟

التعليق الأكثر فائدة

لماذا لا تستخدم np.unravel_index ؟

على سبيل المثال

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

على سبيل المكافأة ، تعمل عندما يكون X أكثر من بُعدين أيضًا.

ال 13 كومينتر

لماذا لا تستخدم np.unravel_index ؟

على سبيل المثال

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

على سبيل المكافأة ، تعمل عندما يكون X أكثر من بُعدين أيضًا.

لست معجبًا بـ argmax2d ، لكن يمكنني إقناعي بـ i, j = a.argmax(axis=(0, 1))

@ eric-wieser كيف تقول أن ذلك يجب أن يتصرف؟ حاليًا يقوم a.argmax() بإرجاع عدد قياسي ، ويقوم a.argmax(axis=0) بإرجاع مصفوفة بشكل الأبعاد المتبقية. أتوقع a.argmax(axis=(0,1)) لمصفوفة ثلاثية الأبعاد لإرجاع مصفوفة من الشكل a.shape[2] .

بغض النظر عن هذه المشكلة ، سيكون من الغريب استخدام a.argmax(axis=range(n)) في الحالة العامة للحصول على مجموعة فهرس طولها n بدلاً من الفهرس الخطي للعدد الصحيح الافتراضي. ربما يمكن تبديل كلمة رئيسية جديدة بين تمثيلات الإخراج؟

ثم مرة أخرى ، كيف سيعمل خيار النتيجة المدرك للشكل هذا مع الكلمة الرئيسية الحالية axis التي تؤدي بالفعل إلى قيمة إرجاع غير قياسية؟

ماذا لو كان أحد الصفوف في صفيفك ثنائي الأبعاد لا يحتوي على حد أقصى (إنه ببساطة مصفوفة ثابتة) - كيف يمكن لـ argmax الإبلاغ عن ذلك؟
على سبيل المثال:

# 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]

سيكون من الجيد أن يكون لديك وسيط إضافي على سبيل المثال للسماح للمستخدم بالتحكم في ما يجب فعله في حالة عدم توفر حد أقصى: np.argmax(x,axis,no_ind=0) (0 افتراضي للحفاظ على التوافق مع الإصدارات السابقة).

@ thoth291 أليس هذا سؤالًا أكثر عمومية فيما يتعلق بسلوك argmax ؟ يحدث نفس الشيء مع عدم وجود وسيطة لكلمة رئيسية axis على مصفوفة 1d:

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

وهذا هو السلوك المعتاد في حالة الروابط: اختر الأول من بين القيم المربوطة. وبالمثل كيف أن max لهذه المصفوفة ليس nan : إنها 2. وإذا كان لديك حد أقصى ، يجب أن يكون لديك فهرس مطابق. أو هل فاتني وجهة نظرك؟

adeak ، لقد
يمكنني الموافقة على أن max([2,2,2]) يساوي 2 .
لكن فكر في argmax ([2،2،2]) - وفقًا للتعريف الوارد في الوثائق الخفية ، فإنها تُرجع the indices corresponding to the first occurrence . يبدو أن هذا لا بأس به من وجهة نظر التنفيذ - لكنه في الحقيقة مجرد عفا عليه الزمن للخوارزمية وليس له علاقة بما يجب أن يحدث بالفعل. يمكن إرجاع أي فهرس بشكل فعال ويجب معاملته على أنه صحيح. أو يمكن للمرء أن يقول أن argmax غامض في حالة المصفوفة ذات القيمة الثابتة.

بعد كل ما قيل ، أفضل تجنب مثل هذا القرار في المقام الأول وإرجاع inf للإشارة إلى أن الأمر متروك للمستخدم لتقرير كيفية التعامل مع مثل هذه الحالة.

وليس له علاقة بما يحدث بالفعل.

هل تقصد "ليس له علاقة بالتعريف المجرد لـ argmax"؟ أتمنى أن لا تكون "الخوارزمية" _ و _ "ما يحدث بالفعل" _ نفس الشيء فحسب ، بل تتطابق مع المستندات.

adeak : آسف لعدم الرد

ثم مرة أخرى ، كيف سيعمل خيار النتيجة المدرك للشكل هذا مع الكلمة الأساسية للمحور الموجودة والتي تؤدي بالفعل إلى قيمة إرجاع غير قياسية؟

أعتقد أن هناك طريقة واحدة واضحة للتعامل مع هذا. كمثال:

>>> 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)

مع ذلك و keepdims ، ستحصل على arr[argmax(arr, axes, keepdims=True)] == max(arr, keepdims=True) مقابل أي بُعد ، والذي يبدو مرغوبًا جدًا بالنسبة لي

في pseudocode ، أتوقع:

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 - التقاط رائع - لقد كتبته أسرع مما كنت قادرًا على الترجمة بشكل صحيح. سوف نكون حذرين في وقت لاحق. تم تحديث التعليق إلى "يجب أن يحدث" بدلاً من "يحدث". آمل أن يساعد ذلك ، وإلا - فتح باب الاقتراحات لإعادة الصياغة.
النقطة المهمة هي أن argmax ([2،2،2]) == 0 جيدة مثل argmax ([2،2،2]) == 1 أو أي شيء آخر ويجب أن يتم اختيارها من قبل المستخدم بدلاً من المكتبة. وبخلاف ذلك ، يجب توفير آلية احتياطية في شكل (على سبيل المثال) كلمة رئيسية إضافية default= أو initial= والتي ستوجه ما يجب إرجاعه في هذه الحالة.

@ thoth291 : نظرًا لأن ما تناقشه ليس خاصًا بـ _2D_ argmax ، أقترح عليك إنشاء عدد جديد

@ eric-wieser لا تقلق ، شكرًا على عودتك إلي. أعتقد أنني أفهم اقتراحك ، ويبدو أنه لا لبس فيه وعملي. حقيقة أن نوع الوسيطة axis يحدد ما إذا كانت قيمة الإرجاع عبارة عن مصفوفة أو مجموعة من المصفوفات أمر مثير للدهشة بعض الشيء بالنسبة لي (خاصة axes=0 مقابل axes=[0] ) ، لكنني متأكد من أن هناك الكثير من الأمثلة الموجودة لنفس السلوك (أيضًا ، التطبيق العملي يتفوق على النقاء).

~ فقط للتأكد: في المثال الخاص بك إذا كان axes=(0,2) فإن الأشكال التي تم إرجاعها يجب أن تكون (B,D,E) ، أليس كذلك؟

فقط للتأكد

كلاهما مصحح ، صيد جيد

حقيقة أن نوع وسيطة المحور تحدد ما إذا كانت القيمة المرتجعة عبارة عن مصفوفة أو مجموعة من المصفوفات أمر مفاجئ بعض الشيء بالنسبة لي

لاحظ أن المصفوفة الفعلية هي نفسها. أعتقد أن هذا يضرب كل من التطبيق العملي والنقاء - القاعدة هي أن axis=(a,)res = (arr,) و axis=ares = arr . Apis أن مجموعات الحالة الخاصة من الحجم 1 تصدمني على أنها فكرة سيئة ، حيث يجب أن يصبح هذا الغلاف الخاص معديًا لمجموعة الاستدعاءات بأكملها

لم أكن لأفكر مطلقًا في مجموعات tuples ذات الطول 1 لحالة خاصة ، هذا يبدو خطأ. كنت أتساءل عن الحالة العددية مقابل الحالة الصفرية. لقد حدث لي بشكل غامض أن الحالات العددية والطول 1 تتطابق مع بعضها البعض بالطريقة التي ذكرتها ، ولكن الآن بعد أن أوضحت ذلك ، من الواضح أن الحالات العددية -> 1-tuple -> حالات tuple العامة هي تعميمات مباشرة. لذا شكرًا ، أنا أؤيد اقتراحك تمامًا.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات