علوم وفضاء

count_nonzero: هل تعود الأعداد إلى المحور الصحيح؟

طبقتا المثال وعد الصف.
C.shape=(3,)؛ K.shape=(1,3,1).

نجح الضرب في المسارين، واختلف الوزن عند الخانة نفسها.

ما الذي بقي بعد عد محورين؟

يمكن عد محورين معًا؛ keepdims يحفظ المحاور المعدودة بطول 1. [1]

نسمي محاور مثالنا طبقة ثم صفًا ثم عمودًا، ونرقمها 0 و1 و2. نريد عدد الخانات غير الصفرية لكل رقم صف عبر الطبقات والأعمدة. ثم نختار مهمة تعليمية: ضرب كل قيمة في العدد الخاص بصفها.

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

قبل التشغيل نكتب أن r هو الفهرس الذي يجب أن يختار الوزن. إذا اتفق طول محورين، لا تكفي قراءة الشكل النهائي لمعرفة أيهما اختار قيمة الوزن.

عد واحد ومحاذاتان ناجحتان

أنشأنا A=np.array([[[0,-4,0],[2,0,0],[0,3,-2]],[[0,0,0],[0,0,5],[7,0,-1]]],dtype=np.int64)، في NumPy 2.3.5 على CPython 3.12.14. شكلها (2,3,3): طبقتان، وفي كل منهما ثلاثة صفوف وثلاثة أعمدة.

شغّلنا C=np.count_nonzero(A,axis=(0,2))، فقرأنا [1,2,4] بالشكل (3,). للصف 0 توجد −4 وحدها في الطبقة الأولى؛ للصف 1 توجد 2 و5؛ للصف 2 توجد 3 و−2 و7 و−1. المجموع 1+2+4=7.

ثم شغّلنا K=np.count_nonzero(A,axis=(0,2),keepdims=True)، فقرأنا K[0,:,0]=[1,2,4] بالشكل (1,3,1). بقي ترتيب الأعداد، مع محور طبقة مفرد ومحور عمود مفرد. سجلنا العد بنوع صحيح؛ ليست الأعداد فهارس مختارة.

قواعد البث تحاذي الأبعاد من اليمين؛ يتوافق طولان إذا تساويا أو كان أحدهما 1. [2]

في شكل K نقابل (1,3,1) مع (2,3,3)، وفي شكل C نقابل (3,) مع آخر محور ذي طول 3. كلا المسارين متوافق في مثالنا. تفسيرنا للمحاذاة يستند إلى القاعدة الموثقة، وليس فحصًا لتنفيذ المكتبة الداخلي. [2]

قرأنا D=A*K وE=A*C، وكلاهما int64 من الشكل (2,3,3). في D، الطبقة الأولى [[0,-4,0],[4,0,0],[0,12,-8]]، والثانية [[0,0,0],[0,0,10],[28,0,-4]].

أما E، فطبقته الأولى [[0,-8,0],[2,0,0],[0,6,-8]]، والثانية [[0,0,0],[0,0,20],[7,0,-4]]. عدد الخانات والشكل متطابقان، والقيم مختلفة.

عند (0,0,1)، قيمة A هي −4. المهمة المقصودة تستخدم C[0]=1 لتعطي −4؛ المسار الآخر استخدم C[1]=2 فأعطى −8. وعند (1,2,0)، ظهرت 7×4=28 مقابل 7×1=7.

قارنا بايتات A قبل الفحوص وبعدها فبقيت ثابتة. استعملنا الضرب لإنشاء الناتجين؛ لا ندعي فحص كتابة داخل A أو ملكية ذاكرة النتائج.

متى تخفي المواضع فرق الوزن؟

نكتب مرجعنا بإحداثيات صريحة: D[p,r,c]=A[p,r,c]×C[r] وE[p,r,c]=A[p,r,c]×C[c]. هذا الوصف خاص بمهمتنا وبالأطوال المتساوية لمحور الصف والعمود؛ لا نجعله صيغة لكل بث.

بطرح المرجعين يكون الفرق A[p,r,c]×(C[r]−C[c]). في حساب الأعداد الصحيحة الصغيرة بلا تجاوز مجال، يساوي الفرق صفرًا إذا كانت قيمة A صفرًا، أو تساوى العددان C[r] وC[c].

لذلك يتساوى المرجعان كاملين إذا وفقط إذا حقق كل موضع غير صفري C[r]=C[c]. تساوي جميع عناصر C كافٍ داخل هذا المرجع، لكنه ليس شرطًا لازمًا. عندما تكون قيم C مختلفة، قد تقع جميع القيم غير الصفرية في مواضع لا تكشف الفرق.

للتحكم، أنشأنا B من الطبقتين [[3,0,0],[0,-2,0],[0,0,0]] و[[0,0,0],[0,7,0],[0,0,0]]، بالنوع والشكل نفسيهما. قرأنا عد المحورين [1,2,0].

لم تكن الأعداد الثلاثة متساوية، لكن القيم غير الصفرية ظهرت عند (0,0,0) و(0,1,1) و(1,1,1). في كل منها r=c، فيختار مرجع الصف ومرجع العمود العدد نفسه.

أعطى مسارا الضرب الطبقتين [[3,0,0],[0,-4,0],[0,0,0]] و[[0,0,0],[0,14,0],[0,0,0]]، من int64 بالشكل (2,3,3). رجعت مقارنة الناتجين True في التشغيل الفعلي.

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

نتيجة الخانة والتحكم القطري.
−4 مقابل −8؛ اتفاق التحكم.

مرجع مستقل ونطاق الفحوص

يبني مرجع Python العدد الخاص بكل صف بمسح الطبقات والأعمدة، وإضافة واحدة إذا اختلفت القيمة الصحيحة عن صفر. ثم يبني الناتجين بمسارين من الإحداثيات الصريحة، وفق وزن الصف أو وزن العمود.

لا يستدعي المرجع count_nonzero أو بث NumPy أو اختزالًا من المكتبة. قابلنا القوائم الكاملة للمثال والتحكم بنتائج التشغيل، ولم نكتف بالخانتين اللتين عرضناهما لتوضيح الفرق.

في الشبكة اخترنا القيم −2 و0 و3 لكل واحدة من الخانات الثماني في الشكل (2,2,2). عدد التوزيعات 3^8=6561؛ يشمل ذلك المصدر الصفري وتوزيعات لها صف لا يحمل أي قيمة غير صفرية.

لكل توزيع ستة فحوص: قائمة C ونوعها وشكلها؛ وقائمة K ونوعها وشكلها مع التحكم بترتيب المحورين (2,0)؛ وقيم D ونوعها وشكلها؛ وقيم E ونوعها وشكلها؛ وشرط اتفاقهما وفق المواضع غير الصفرية؛ وثبات بايتات المدخل ونوعه وشكله وعد الخانات المطابقة.

أضفنا ستة فحوص للمثال وستة للتحكم القطري. صار المجموع 6561×6+12=39378، ومرت جميعها. تساوى العد عند عكس ترتيب المحورين في الحالات المفحوصة؛ لا ندعي فحص كل محاور المكتبة.

نقصر الأدلة على int64 والأعداد الصغيرة المذكورة، والمحورين (0,2) وتحكم ترتيب (2,0)، مع تساوي طولي الصف والعمود. لا تشمل الاختبارات أطوالًا صفرية أو رتبًا وأشكالًا ومحاور أخرى، أو النصوص والكائنات والقيم المركبة وNaN واللانهاية.

لم نقسم على الأعداد، بما فيها الصفر في التحكم؛ لم نفحص تجاوز المجال أو الأداء أو ملكية الذاكرة. لا تعني القيمة غير الصفرية أن سجلًا واقعيًا صالح؛ لا تتناول مهمتنا أصل البيانات أو تنظيفها.

احفظ شكل A والمحورين وعد C وشكل K، ثم اربط خانة من الناتج بفهرس الوزن الذي قصدته. في المثال كشف ذلك فرق −4 و−8، وفي التحكم فسّر لماذا أخفته المواضع القطرية.

البطاقةCK.shapeاتفاق الناتجين
المثال[1,2,4](1,3,1)False
التحكم القطري[1,2,0](1,3,1)True

للتوسع: المتوسط والمحور والشكل.

المراجع

  1. NumPy 2.3 — count_nonzero
  2. NumPy 2.3 — broadcasting

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