قد تنقل طلبًا بين rollaxis وmoveaxis مع إبقاء أرقام الوسائط، فتظن أن ترتيب المحاور سيبقى نفسه. سجلنا مثالًا يوضح أن الرقم الأخير يحتاج إلى قراءة معناه في كل عملية، ثم تابعنا قيمة عند فهرس صالح في الناتجين.
اقرأ موضع البداية ووجهة النقل
إذا start<=axis يصبح المحور في start؛ وإذا start>axis يصبح قبله. [1]
تحدد destination الموضع النهائي في moveaxis، مع حفظ ترتيب المحاور الأخرى. [2]
سنقصر الأمثلة على ثلاثة محاور مرقمة 0 و1 و2، وطلبات مفردة بأرقام غير سالبة من هذا المجال. قبل حساب الأعداد نكتب ترتيب هويات المحاور، لا أطوالها فقط.
الرقم 2 في الطلبين لا يعني الموضع نفسه
أنشأنا A من int64 بالشكل (2,3,4). قيمة الموضع (i,j,k) مؤلفة بصيغة 9+100*i+10*j+k، فتظل عناوين القيم ظاهرة؛ مثلًا A[0,1,1]=20 وA[1,1,0]=119. شغّلنا NumPy 2.3.5 على Python 3.12.14.
نفذنا np.rollaxis(A,0,2). بما أن 2 أكبر من 0، يأتي المحور الأصلي 0 قبل الموضع المشار إليه. ترتيب المحاور الأصلية المسجل [1,0,2]، والشكل (3,2,4). نقلناه إلى الموضع النهائي 1 في هذا الطلب.
أما np.moveaxis(A,0,2) فسجلت ترتيب [1,2,0] والشكل (3,4,2): المحور الأصلي 0 صار الأخير. لا نستبدل الرقم 2 بالرقم 2 دون متابعة معنى الوسيط الذي أخذه.
الفهرس (1,0,1) صالح في الشكلين. في الناتج الأول يقابل الأصل (0,1,1)، فيقرأ 20؛ وفي الثاني يقابل (1,1,0)، فيقرأ 119. لم تتغير صيغة A، بل تغيرت هوية المحور الذي تفسره كل خانة من الفهرس.
لإعادة ترتيب الطلب الأول نفسه بصيغة moveaxis في مثالنا، تكون الوجهة 1. هذا حساب لترتيب المحاور المعلن، وليس قاعدة نقل للأرقام السالبة أو لقائمة محاور متعددة لم نختبرها.
تحكم تتفق فيه الوجهتان
أبقينا A نفسها، واخترنا rollaxis(A,2,0) وmoveaxis(A,2,0). في التشغيل المسجل أعادت العمليتان ترتيب [2,0,1]، والشكل (4,2,3)، والقيم نفسها. الفهرس (1,0,1) عاد إلى الأصل (0,1,1) في كليهما، فقرأ 20.
أزال هذا التحكم حالة start>axis التي ظهر فيها الفرق الرئيسي. لا نعامل تطابقه دليلًا على أن نسخ الوسائط يصلح لكل طلب؛ نراجع شرط العلاقة بين الرقميْن أولًا.
في جميع الحالات المختبرة بقيت بايتات A ثابتة، وشارك كلا الناتجين ذاكرتها. سجلنا ذلك في هذا النطاق دون كتابة عبر النتائج؛ تطابق التخزين المشترك هنا لا يعني تطابق ترتيب المحاور، ولا نقيس به أداء العمليتين.

مرجع إحداثيات وحدود الفحص
بنى مرجع Python قائمة المحاور بعد حذف المحور المطلوب، ثم أدخله في start عندما axis>=start، أو في start-1 للطلب الأول عندما axis<start. أما قائمة الوجهة النهائية فأدخلته في start. بعد ذلك كوّن قوائم الناتج بحساب عنوانه في الأصل وصيغته العددية.
لم يستدع المرجع rollaxis أوmoveaxis أوtranspose أوreshape. لكل خانة جديدة وضع مكونات فهرسها في مواقع المحاور الأصلية، ثم حسب 9+100*i+10*j+k للمثال، أو100*i+10*j+k لشبكة الفحص.
اخترنا أطوالًا من 1 إلى 3 لكل محور: 3³=27 شكلًا. لكل شكل، ثلاثة اختيارات للمحور وثلاثة لـstart من 0 إلى 2، أي 27×3×3=243 حالة. أضفنا المثال والتحكم ذوي الطول 4 والإزاحة 9 خارج الشبكة، فصار العدد 245.
لكل حالة خمس مجموعات تحقق: قيم rollaxis وشكلها ونوعها، وقيم moveaxis وشكلها ونوعها، وشرط اتفاق ترتيب المحاور عند axis>=start، وثبات بايتات المصدر، ومشاركة الناتجين لذاكرته. المحصلة 245×5=1225، ومرت كلها.
اختلف ترتيب المحاور في 82 حالة، منها المثال الرئيسي. هذا عد لترتيب الهويات، وليس عدد حالات اختلاف القيم؛ محور بطول واحد قد يخفي اختلاف الترتيب في الشكل والقيم. لذلك نحتفظ بالقائمة الوصفية مع المخرجات بدل الاكتفاء بالمقارنة العددية.
النطاق ثلاثة محاور وint64 وأطوال موجبة وطلب محور واحد. لم نفحص أرقامًا سالبة، أوstart=3، أوطلبات غير صالحة، أونقل محاور متعددة، أوأنواعًا وأبعادًا أخرى، أوأطوالًا صفرية، أوتعديل النتائج والسرعة. عند تحويل طلب، حدد موضع المحور النهائي المقصود ثم تابع عنوان قيمة معلومة.
| الطلب | ترتيب المحاور الأصلية | الشكل | القيمة عند (1,0,1) |
|---|---|---|---|
| rollaxis(A,0,2) | 1,0,2 | 3,2,4 | 20 |
| moveaxis(A,0,2) | 1,2,0 | 3,4,2 | 119 |
| كلا الطلبين من 2 إلى 0 | 2,0,1 | 4,2,3 | 20 |
للتوسع: متجه أحادي البعد وإضافة المحور.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
