علوم وفضاء

squeeze في NumPy: أي محور بطول واحد نحذف؟

C بالشكل 1 في 2 في 1 في 3 يحمل القيم 2 وسالب 4 و8؛ 7 و3 و6. حذف المحور 2 فقط يعطي 1 في 2 في 3، والحذف الافتراضي يعطي 2 في 3. القيم الست نفسها.
شكلان مختلفان للقيم نفسها؛ نحدد المحاور المحذوفة.

squeeze يزيل محاور طولها واحد؛ اختيار أطول يرفع ValueError. [1]

اختر محورًا طوله واحد

squeeze يزيل المحاور ذات الطول واحد؛ اختيار محور ليس طوله واحدًا يرفع ValueError. [1]

نؤلف C=[[[[2,-4,8]],[[7,3,6]]]]. الشكل (1,2,1,3): محور 0 طوله 1، ومحور 1 طوله 2، ومحور 2 طوله 1، ومحور 3 طوله 3. يبدأ ترقيم المحاور من صفر، والأعداد بلا وحدة وليست بيانات تدريب جديدة.

للقراءة الواضحة، نكتب القيم في صفين: [2,-4,8] و[7,3,6]. هذا عرض للقيم الست؛ لا يختزل المحاور الأربعة المعلنة إلى محورين. أقواس C المتداخلة تحفظ مستوى خارجيًا واحدًا ومستوى بطول واحد بين المحورين ذوي الطولين 2 و3.

نختار axis=2، فنزيل المحور الثالث، ذي الطول واحد. يبقى (1,2,3)، وتصبح كتابة التنظيم [[[2,-4,8],[7,3,6]]]. بقي المحور الخارجي بطول 1؛ لم نختر حذفه.

إذا اخترنا axis=0 وحده بدلًا من 2، يصبح الشكل (2,1,3)، والتنظيم [[[2,-4,8]],[[7,3,6]]]. عدد القيم ستة في الحالتين، لكن موضع طول الواحد الباقي مختلف.

أما axis=1 فطوله 2. لا نحذف أول الصفين أو نجمعهما حتى نكمل طلب squeeze؛ هذا الاختيار لا يحقق شرط طول الواحد. في نموذجنا المستقل نرفضه، ونستند إلى التوثيق في تسمية الاستثناء دون ادعاء أننا شغلنا NumPy.

افحص الحذف الافتراضي

squeeze الافتراضي يزيل محاور طولها واحد؛ حذفها كلها يعطي مصفوفة بالشكل ()، لا عددًا من بايثون. [1]

في C، المحوران 0 و2 هما بطول 1. حين نحذفهما معًا، يبقى الشكل (2,3)، وتصبح القيم [[2,-4,8],[7,3,6]]. لا يبقى محور خارجي بطول واحد، خلاف نتيجة اختيار axis=2 وحده.

عدد القيم محفوظ في الحساب: 1×2×1×3=6 قبل العملية، و2×3=6 بعدها. حذف عامل يساوي واحدًا من وصف الأبعاد لا يقسم الأعداد أو يزيل نصفها. أما عدد المحاور فينخفض من 4 إلى 2.

نؤلف حالة أخرى: D من قيمة واحدة هي 11، موضوعة في شكل (1,1,1). كل محور طوله واحد. الحذف الافتراضي يزيل المحاور الثلاثة، فيكون الشكل ()، وما زالت لدينا القيمة 11.

الشكل () لا يعني طولًا يساوي صفرًا، ولا يعني مصفوفة عددية كل عناصرها أصفار. إنه وصف بلا محاور. نميز ذلك عن تنظيم بمحور واحد طوله 1، وعن تنظيم بمحور طوله 0 لا يحمل عناصر.

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

احفظ هوية المحاور الباقية

نسمي محاور C أسماء مؤلفة: إطار، وصف، وقناة، وعمود. الأطوال على الترتيب 1 و2 و1 و3. هذه الأسماء قرار في المثال؛ لا تفرضه المكتبة على الأعداد.

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

بعد الحذف الافتراضي، المحور الأصلي 1، الذي سميناه صفًا، صار المحور 0 في الناتج. والمحور الأصلي 3، المسمى عمودًا، صار المحور 1. لا نمرر الأرقام الأصلية 1 و3 إلى الناتج ذي المحورين وكأنها ما زالت صالحة.

نتابع العنصر 8 مثلًا. فهرسه الأصلي (0,0,0,2). بعد حذف المحور 2 فقط يصير (0,0,2)، وبعد الحذف الافتراضي يصير (0,2). ما تغير في هذا المسار هو عدد مكونات الفهرس، ولم يتغير العدد 8 نفسه.

قولنا طول المحور 1 لا يعني أن قيمته العددية 1. المحور يصف عدد المواضع المسموح بها في ذلك الاتجاه. C يحتوي 2 و−4 و8 و7 و3 و6، ولا يحتاج عنصرًا يساوي 1 لكي يكون له محور بطول واحد.

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

بعد الحذف الافتراضي يصبح C بالشكل 2 في 3. إدراج محور عند 2 يعطي 2 في 3 في 1، بينما إدراج 0 ثم 2 يعيد 1 في 2 في 1 في 3.
مواضع الإضافة محسوبة لكل خطوة؛ الشكل الأصلي يحتاج المحورين.

أعد المحور في مكانه

expand_dims يدرج محورًا جديدًا في الموضع المحدد في شكل الناتج. [2]

نبدأ بنتيجة اختيار axis=2 من C، وشكلها (1,2,3). ندخل محورًا بطول 1 في الموضع 2، فتصير (1,2,1,3). نستعيد كتابة C وتوزيع القيم في نموذجنا، لأننا حفظنا موضع المحور الذي أزلناه.

لكن البدء بنتيجة الحذف الافتراضي، ذات الشكل (2,3)، يغير السؤال. إدخال محور في الموضع 2 يعطي (2,3,1). هذه ثلاثة محاور، بينما C كانت بأربعة؛ والمحور المضاف هنا يأتي بعد طول 3، لا قبله في تنظيم C.

لا تكفي كتابة اسم العملية العكسية لاستعادة كل المحاور. نحتاج في هذه الحالة خطوتين: إدخال محور في الموضع 0 يجعل الشكل (1,2,3)، ثم إدخال محور في الموضع 2 يعطي (1,2,1,3). نحسب الأرقام بالنسبة إلى الشكل الموجود عند كل خطوة.

لو عكسنا الخطوتين، لأضفنا عند 2 أولًا إلى (2,3)، فنحصل على (2,3,1)، ثم عند 0 فنصل إلى (1,2,3,1). عدد القيم ما زال 6، لكن موضع طول الواحد الأخير لا يطابق الشكل الأصلي.

نطاق الحساب أطوال محاور موجبة ومدخل صحيح من بعد واحد إلى أربعة؛ محاور إزالة مختلفة وصحيحة غير سالبة، وطول كل مختار 1، وموضع إدراج مفرد صحيح غير سالب. نقصر الأخطاء على رفض إزالة محور أطول. لم نشغل NumPy أو نفحص الذاكرة أو النسخ أو الزمن أو نموذج تعلم؛ الاختبارات تتتبع الشكل والمواضع والقيم.

الاختيارالشكل الناتجما بقي من المحاور
squeeze: axis=2(1,2,3)إطار، صف، عمود
squeeze: axis=0(2,1,3)صف، قناة، عمود
squeeze: الافتراضي(2,3)صف، عمود
squeeze: axis=1ValueErrorالمحور طوله 2
بعد الافتراضي، إدراج 2(2,3,1)ثلاثة محاور
بعد الافتراضي، إدراج 0 ثم 2(1,2,1,3)الشكل الأصلي

للتوسع: الأبعاد والقطر والمنقول.

المراجع

  1. NumPy — squeeze
  2. NumPy — expand_dims

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