في مثالنا، بقي صفان صفريان وعمود صفري داخل المستطيل المقصوص.
المستطيل لا يحذف كل صف صفري
axis=None يختار أصغر صندوق يحوي غير الأصفار؛ المحور المحدد يقصر القص عليه. [1]
نسأل عن فرق ملموس: هل القص يحفظ مستطيلًا متصلًا من مواضع المصدر، أم يجمع الصفوف والأعمدة التي فيها قيم غير صفرية؟ نختبر السؤال على جدول مؤلف ذي قيمتين فقط.
في NumPy 2.3.5 على CPython 3.12.14، أنشأنا A=np.zeros((6,7),dtype=np.int64)، ثم وضعنا −6 عند A[1,2] و9 عند A[4,4]. جميع الأعداد بلا وحدة قياس؛ ليست صورة أو سجلًا واقعيًا.
أعطى np.trim_zeros(A) الشكل (4,3) والقيم [[-6,0,0],[0,0,0],[0,0,0],[0,0,9]]. الصفان الأوسطان كلاهما صفري، والعمود الأوسط صفري أيضًا، ومع ذلك بقوا داخل الناتج.
المستطيل المطلوب في مثالنا يمتد من صف المصدر 1 إلى 4، ومن العمود 2 إلى 4. أقصى الصفوف والأعمدة تحددهما القيمتان المؤلفتان. الصفوف الواقعة بينهما لا تصبح هامشًا خارجيًا لمجرد أن عناصرها أصفار.
لو جمعنا الصفين ذوي القيم غير الصفرية والعمودين ذوي القيم غير الصفرية فقط، لتقلص الشكل إلى (2,2). هذه مقارنة هندسية مستقلة؛ لم ننفذها بوصفها استدعاء trim_zeros، ولا ننسبها إلى المكتبة.
قارن المستطيل بقص محور واحد
حدود المستطيل في مرجعنا هي الصفوف 1:5 والأعمدة 2:5؛ حد التوقف مستبعد في بطاقة الإحداثيات التي نبنيها. طوله على المحور الأول 5−1=4، وعلى الثاني 5−2=3.
العنصر الجديد عند (0,0) يقابل (1,2) في A، والعنصر الجديد عند (3,2) يقابل (4,4). بين صفّيهما صفا المصدر 2 و3، وبين عموديهما عمود المصدر 3. تبقى هذه المواضع كلها في المستطيل.
استدعينا np.trim_zeros(A,axis=0). ظهر الشكل (4,7): احتفظنا بالصفوف 1 إلى 4 وبالأعمدة السبعة كاملة. الأعمدة الطرفية الصفرية لم تُقص في هذه البطاقة.
ثم استدعينا np.trim_zeros(A,axis=1). ظهر الشكل (6,3): الصفوف الستة كاملة، والأعمدة 2 إلى 4. الصفان الطرفيان الصفريان بقيا هنا لأننا قصرنا التجربة على محور الأعمدة.
اختبرنا trim="f" و"b" و"fb" للبداية والنهاية والطرفين. البداية طرف الفهرس الأقل والنهاية طرف الأعلى. [1]
مع axis=None، البداية فقط أعطت الشكل (5,5)، من صفوف المصدر 1:6 وأعمدته 2:7. النهاية فقط أعطت أيضًا (5,5)، لكن من الصفوف 0:5 والأعمدة 0:5. قص الطرفين أعطى (4,3).
الشكلان المتساويان لا يعنيان قيمًا أو إحداثيات متساوية: في بطاقة البداية تقع −6 عند (0,0)، وفي بطاقة النهاية عند (1,2). كتبنا حدود المصدر إلى جانب كل شكل حتى لا نستنتج موضع العنصر من أبعاد الناتج وحدها.
بقي نوع الناتج int64 ورتبته اثنين في البطاقات التسع: ثلاثة اختيارات للمحور وثلاثة للطرف. تحققنا من قيم كل بطاقة وشكلها ومن ثبات بايتات A خلال الفحوص؛ لم ننفذ كتابة إلى الناتج.
التسطيح أولًا يغير مسار القص
ravel تعيد ترتيب العناصر في متجه؛ في order="C" يتغير فهرس المحور الأخير أسرع. [2]
حددنا ترتيب C صراحة باستدعاء np.ravel(A,order="C"). تحققنا أن المتجه يحتوي صف المصدر 0 ثم 1 حتى 5، وفي كل صف الأعمدة من 0 إلى 6. شكله (42,) لأن 6×7=42.
في نموذج فهارسنا، الفهرس المسطح هو 7r+c. لذلك تقع −6 عند 7×1+2=9، وتقع 9 عند 7×4+4=32. الباقي أصفار؛ لا نغير قيم الجدول قبل التسطيح.
شغّلنا trim_zeros على هذا المتجه؛ خرج الشكل (24,). يوافق المقطع المؤلف 9:33، وطوله 33−9=24. يضم نهاية الصف 1، والصفين 2 و3 كاملين، وبداية الصف 4 حتى العمود 4.
هذا المقطع ليس تسطيح المستطيل ذي الشكل (4,3). المستطيل يأخذ الأعمدة 2 و3 و4 من كل واحد من الصفوف الأربعة، فعدد عناصره 4×3=12. تحققنا أن تسطيحه بترتيب C أعطى الشكل (12,).
احتفظ المساران بقيمتي −6 و9، لكن مجموعة المواضع بينهما مختلفة. المقطع المسطح يحتفظ بأعمدة طرفية من بعض الصفوف لأن تلك المواضع تقع بين الفهرسين 9 و32 في المتجه.
لا يكفي عدد غير الأصفار، وهو اثنان في المثال، لمساواة الشكلين. نحفظ ترتيب التسطيح وحدود المصدر حتى لا نسمي المقطع المسطح مستطيلًا مقصوصًا.
الأصفار الداخلية جزء من هندسة الجدول المؤلف هنا. لم نقرر أنها قيم مفقودة أو غير صالحة، ولم نحول القص إلى توصية لمعالجة صورة أو قياسات. تفسير الصفر في بيانات أخرى يحتاج أدلة تلك البيانات.

مرجع الإحداثيات ونطاق الأدلة
جمع مرجع Python المستقل جميع أزواج (r,c) التي لا تساوي قيمتها صفرًا. لبناء حد كل محور، أخذ أصغر فهرس وأكبره زائد واحد عندما يُقص ذلك الطرف؛ أما الطرف غير المطلوب فيبقى عند حد المصدر.
عند axis=None طبّق المرجع ذلك على المحورين؛ وعند axis=0 أو1 طبّقه على المحور المعين وحده. جمع القيم بحلقتين من قائمة المصدر داخل الحدود، دون استدعاء trim_zeros في مرجع التوقع.
للشبكة أخذنا جميع جداول الشكل (2,3) بقيم من −2 وصفر و3، واستبعدنا الجدول الصفري بالكامل. العدد 3**6−1=728. لكل جدول اختبرنا المحاور None و0 و1 مع fb وf وb، فصار العدد 728×9=6552.
أضفنا تسع بطاقات لجدولنا (6,7). لكل حالة خمسة فحوص: القيم والشكل والنوع والرتبة؛ مطابقة الإحداثيات الجديدة بمواضع المصدر؛ بقاء عدد غير الأصفار؛ ثبات الناتج عند تكرار القص نفسه؛ وثبات بايتات المدخل وشكله.
أضفنا أربعة فحوص رئيسية للتسطيح: ترتيب متجه A وشكله؛ قيم المقطع المسطح ونوعه وشكله؛ قيم المستطيل وشكله؛ واختلاف طول المقطع المسطح عن طول تسطيح المستطيل. المجموع (6552+9)×5+4=32809، ومرت جميعها.
النطاق المعلن int64 ثنائي البعد، بأحجام موجبة ووجود عنصر غير صفري، والمحاور None و0 و1 فقط. لا يشمل مدخلًا فارغًا أو صفريًا بالكامل، أو محاور أخرى أو رتبًا وأنواعًا أخرى أو NaN واللانهاية.
لم نفحص ملكية الذاكرة أو أثر كتابة في الناتج أو الأداء أو المساحة التي تتحرر. صحة الإحداثيات والشكل لا تثبت أيًا من ذلك. عند مراجعة المثال، نربط الناتج بالمحور والطرف وحدود المصدر وترتيب التسطيح.
| المسار على A | شكل الناتج | حدود المصدر في المرجع |
|---|---|---|
| axis=None; fb | (4,3) | rows1:5 / cols2:5 |
| axis=0; fb | (4,7) | rows1:5 / cols0:7 |
| axis=1; fb | (6,3) | rows0:6 / cols2:5 |
| axis=None; f | (5,5) | rows1:6 / cols2:7 |
| axis=None; b | (5,5) | rows0:5 / cols0:5 |
| ravel(C), then trim | (24,) | flat9:33 |
للتوسع: الأبعاد ومكان العنصر.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
