تقنية

unravel_index: هل −1 يعني آخر موضع؟

فهرسان معلنان.
خطأ وإحداثيان مسجلان.

على الشكل (4,5)، رفعت unravel_index خطأ ValueError عند الفهرس −1، بينما حولت19 إلى الإحداثيين (3,4). مصفوفة int64 مستقلة تحمل0 إلى19 أعادت19 عند a[-1]. سنحفظ الفرق بين تحويل موضع وقراءة قيمة.

موضع مسطح أم قيمة مقروءة؟

تحول unravel_index الفهرس المسطح إلى إحداثيات باستخدام الشكل وترتيب الفهرسة المعلنين. [1]

تقبل الفهرسة العادية للعنصر فهارس سالبة للعد من النهاية. [2] هذا وصف لقراءة العنصر في المصفوفة؛ سنقارنه بإجراء يحول رقم موضع إلى إحداثيات.

نختار شكلًا افتراضيًا (4,5): أربعة صفوف وخمسة أعمدة، وفهارس تبدأ من صفر. نكتب رقم الصف قبل العمود. لا نحتاج إلى وضع قياسات في جدول لكي نحسب إحداثيات موضع فيه.

عدد عناصر المصفوفة حاصل ضرب أطوال محاورها. [3] في الشكل المعلن4×5=20 موضعًا. الرقم19 هو آخر فهرس غير سالب هنا؛ العدد20 هو عدد المواضع، وليس رقم الموضع الأخير.

ولتحكم القراءة نبني مصفوفة مستقلة ذات محور واحد تحمل الأعداد0 إلى19 من int64. اخترنا أن توافق قيمها أرقام مواضعها للوضوح؛ في بيانات أخرى قد تكون القيمة المقروءة مختلفة عن رقم فهرسها.

السالب يرفض والصالح يتحول

في NumPy 2.3.5 وCPython 3.12.14 استدعينا np.unravel_index(-1,(4,5)) دون order مخصص. رفعت builtins.ValueError. حفظنا رسالة تقول إن الفهرس−1 خارج حدود مصفوفة حجمها20؛ لم يرجع النداء إحداثيين.

لا نسجل (3,4) بوصفها نتيجة لهذا النداء الفاشل، ولا نستبدل−1 بالعدد19 داخل سجل المدخل ثم نكتب أن السالب نجح. نحتفظ بالطلب الأصلي ونوع الخطأ الذي وقع عليه.

في نداء مستقل نفذنا np.unravel_index(19,(4,5)). عاد tuple يحوي القيمتين3 و4؛ كل منهما numpy.int64 في هذا التشغيل. هنا المدخل فهرس صحيح مفرد، وليست مصفوفة فهارس متعددة.

ترتيب C يقرأ الصفوف، وF يقرأ الأعمدة. [1] استعملنا C الافتراضي فقط. حسب المرجع divmod(19,5)=(3,4): خارج القسمة يحدد الصف، والباقي يحدد العمود.

تبدأ مواضع الصف الأخير من15 إلى19، ويقع19 في العمود ذي الفهرس4. هذا يفسر الإحداثيين المعلنين؛ لم نشغل وضع F أو نفترض أن تبديل اسم الترتيب يحافظ على معنى كل موضع.

الرسم يحفظ صف الخطأ منفصلًا عن صف العودة الناجحة. رسالة الخطأ ليست عددًا ولا فهرسًا خاصًا رجع من الدالة، وغياب العودة ليس زوجًا من قيم فارغة اخترعناه.

قراءة من النهاية ومدخل مختلط

أنشأنا a=np.array(list(range(20)),dtype=np.int64)، بالشكل (20,). في قراءة a[-1] رجعت القيمة19 من numpy.int64. هذا نداء قراءة عنصر، وليس استخراج إحداثيي الصف والعمود من الشكل (4,5).

حتى مع توافق القيمة19 مع آخر رقم موضع في هذا التحكم، تبقى العودتان مختلفتين: القراءة أعادت عددًا واحدًا، والتحويل الصالح أعاد زوج الإحداثيين3 و4. لا نستبدل أحد الوصفين بالآخر لأننا اخترنا قيمًا سهلة التتبع.

ثم أنشأنا ix=np.array([-1,19],dtype=np.int64)، بالشكل (2,). استدعينا np.unravel_index(ix,(4,5)). رفعت ValueError برسالة عن−1 خارج حدود الحجم20.

لم يرجع هذا النداء زوج مصفوفات يضع نتيجة صالحة للعدد19 وحالة خاصة للعدد−1. قبول19 في النداء المفرد السابق لا يعني نجاح المدخل المختلط؛ نسجل نتيجة كل محاولة على حدة.

بقيت ix بالقيمتين−1 و19، وبقيت a تحمل الأعداد الأصلية. راجعنا الأنواع والأشكال والبايتات قبل المحاولات وبعدها؛ لم نعدل الفهرس السالب في المدخل، ولم نكتب قيمة جديدة عبر القراءة.

لم نشغل التفافًا أوقصًا أوravel_multi_index أوعملية باقي لتصحيح الطلب. الفرق الذي نعرضه هو ما أعادته القراءة العادية وما رفضه تحويل الفهرس المسطح على المدخلات المعلنة.

قراءة ومدخل مختلط.
عودات محفوظة.

عد العودات وحدود المرجع

اخترنا17 شكلًا (r,5)، حيث r من3 إلى19. لكل شكل المجموع5r، وآخر فهرس5r−1. نبني مصفوفة بيانات0 إلى5r−1، ومصفوفة فهارس [-1,5r−1] من int64، فيصير عدد مصفوفات المدخل34.

لكل شكل أربع محاولات: تحويل−1، وتحويل المصفوفة المختلطة، وتحويل آخر فهرس صالح، ثم قراءة آخر عنصر بالفهرس−1. العدد17×4=68 نداءً مسمى. إعداد المصفوفات وفحوص خصائصها لا يدخلان في هذا العدد.

محاولتا التحويل السالب والمختلط أعطتا34 سجل ValueError. التحويل الصالح أعطى17 زوجًا، والقراءة أعطت17 قيمة مفردة؛ صارت العودات الناجحة34، والقيم العددية المحفوظة17×2+17=51.

لا نعد الزوج مخرجي نداءين، ولا نعد سجل الخطأ عودة عددية. ولم ترجع النداءات الناجحة مصفوفة bool أو مصفوفة أعداد؛ أنواع عناصر الأزواج والقيم المفردة محفوظة مع كل سجل.

بنى مرجع Python المتوقع من القوائم المعلنة والقسمة والباقي؛ آخر موضع صالح يعطي (r−1,4)، وقراءة القائمة من النهاية تعطي5r−1. أعلننا توقع رفض السالب والمختلط، ثم قابلناه بالنتيجة الفعلية، دون استعمال تحويل NumPy لتوليد المتوقع.

تحققنا من بايتات المدخلات بواسطة struct، ومن اختلاف تمثيلاتها البايتية الأربعة والثلاثين وثباتها. حفظ الخطأ أوالقيمة وحدهما لا يعوض توثيق الشكل الذي استعمل لتحويل الفهرس.

النطاق الأشكال الموجبة المذكورة وترتيب C وفهرس−1 وآخر فهرس صالح وint64. لم نفحص سالبًا آخر أوالحد الأعلى أوF أوبثًا أوshape فارغًا أوأبعادًا مفردة أوفهارس عائمة أوأنواعًا أخرى أوكتابة أونسخًا أوذاكرة أوأداءً أوإصدارًا آخر.

Own callInputOutcome
unravel_index / (4,5)-1ValueError
unravel_index / (4,5)19(3,4)
ordinary a[-1]data 0..1919
unravel_index / (4,5)[-1,19]ValueError

للتوسع: ترتيب الفهارس.

المراجع

  1. NumPy unravel_index
  2. NumPy indexing
  3. NumPy ndarray.size

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