سؤال

في Numpy ، دعنا نقول أن لديك ND-Array A ، يمكنك تقطيع البعد الأخير عن طريق العمل A[...,0] أو يمكنك تقطيع البعد الأول عن طريق القيام به A[0]. أرغب في تعميم هذه العملية لجميع الأبعاد (وليس فقط أولاً أو أخيرة) وأريد هذا الأمر لـ ND-Array of التعسفي n بحيث إذا كان A3 عبارة func(A3, dim = 1, slice = 0) أعطني A3[ : , 0 , :] و func(A4, dim = 1, slice = 0) أعطني A4[ : , 0 , : , : ].

لقد بحثت عن هذا لبعض الوقت وأخيراً اكتشفت كيفية القيام بذلك دون القيام بالاختراق الرهيب (مثل تبديل البعد حتى يكون الاهتمام في المكان الأخير). لذا فإن الرمز الذي أنشره هنا يعمل من أجل حاجتي ولكن

1) أنا أبحث دائمًا عن نصيحة لتحسين نفسي

2) كما قلت ، لقد بحثت عن هذا لبعض الوقت ولم أجد أي شيء حتى لا يكون مفيدًا للآخرين.

def fancy_subarray(farray, fdim, fslice):
    # Return the farray slice at position fslice in dimension fdim

    ndim = farray.ndim

    # Handle negative dimension and slice indexing
    if fdim < 0:
        fdim += ndim
    if fslice < 0:
        fslice += v.shape[fdim]

    # Initilize slicing tuple
    obj = ()

    for i in range(ndim):
        if i == fdim:
            # Only element fslice in that dimension
            obj += (slice(fslice, fslice+1, 1),)
        else:
            # "Full" dimension
            obj += (slice(None,None,1),)

    return farray[obj].copy()

لذا فإن هذه الوظيفة الصغيرة تبني فقط تشريحًا عن طريق التسلسل slice(None,None,1) في موقف البعد لا نريد شريحة و slice(fslice, fslice+1, 1) في بُعد الاهتمام. انها من إرجاع سفر تحت. إنه يتعامل مع الفهارس السلبية.

هناك اختلاف بسيط في هذا وفهرسة مباشرة: إذا كان A3 هو 3x4x5 ، A3[:,0,:] سيكون 3x5 بينما fancy_subarray(A3, fdim = 1, fslice = 0) سيكون 3x1x5. أيضا وظيفة وظيفة خارج البعد المربوطة والفهارس "بشكل طبيعي". إذا fdim >= farray.ndim تعمل الوظيفة فقط على إرجاع المصفوفة الكاملة لأن الشرط IF داخل الحلقة لم يكن صحيحًا أبدًا وإذا fslice >= farray.shape[fdim] سيكون لحجم 0 في البعد.

يمكن بسهولة تمديد هذا إلى أكثر من مجرد اختيار عنصر واحد في بعد واحد بالطبع.

شكرًا!

هل كانت مفيدة؟

المحلول

أعتقد أنك تعوض عن الأشياء ، خاصة عند التعامل معها fslice. إذا فعلت ببساطة:

def fancy_subarray(farray, fdim, fslice):
    fdim += farray.ndim if fdim < 0 else 0
    index = ((slice(None),) * fdim + (fslice,) +
             (slice(None),) * (farray.ndim - fdim - 1))
    return farray[index]

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

>>> fancy_subarray(a, 1, 2)
array([[10, 11, 12, 13, 14],
       [30, 31, 32, 33, 34],
       [50, 51, 52, 53, 54]])
>>> fancy_subarray(a, 1, slice(2,3))
array([[[10, 11, 12, 13, 14]],

       [[30, 31, 32, 33, 34]],

       [[50, 51, 52, 53, 54]]])
>>> fancy_subarray(a, 1, [2, 3])
array([[[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]],

       [[50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top