علوم وفضاء

insert: هل الفهرس المفرد وقائمة العنصر الواحد يتكافآن؟

كتلتان مختلفتا العرض في الناتجين.
قيمة لكل صف أو قيمتان داخل كل صف.

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

احفظ شكل الفهرس والقيم

insert تدرج قبل الفهرس على المحور؛ الفهرس المفرد وتسلسل العنصر الواحد قد يختلفان. [1]

نختار السؤال التالي: هل وجود الرقم 1 مرة واحدة في وسيط obj يكفي لتوقع عمود واحد جديد؟ سنقارن تمثيل الرقم وتمثيل القيم مع تثبيت الجدول والمحور.

في NumPy 2.3.5 على CPython 3.12.14، أنشأنا A=np.array([[5,-1,8],[2,7,-4]],dtype=np.int64)، وV=np.array([10,20],dtype=np.int64). شكل A هو (2,3)، وشكل V هو (2,).

للإعداد الآخر نكتب indices=list((1,))، وهي قائمة ذات عنصر واحد قيمته 1. نقابل obj=1 مع obj=indices؛ عدد الفهارس المختارة واحد في كل منهما، لكن أحد الوسيطين عدد والآخر تسلسل.

نحدد axis=1 صراحة، ونقصد الإدراج قبل العمود ذي الفهرس 1. أسماء الصف والعمود تخص مثالنا الثنائي؛ الفهارس تبدأ من صفر، والأعداد مؤلفة بلا وحدة أو بيانات ملف حقيقي.

نحفظ شكل V إلى جانب عدد عناصره. لاحقًا سنقدم القيمتين نفسيهما في مصفوفة عمودية من الشكل (2,1)، كي يظهر أثر تنظيم القيم بصورة منفصلة عن تغيير الأعداد.

عمود واحد أو كتلة من عمودين

أعطى S=np.insert(A,1,V,axis=1) الجدول [[5,10,-1,8],[2,20,7,-4]] من int64 وبالشكل (2,4). لكل صف قيمة مدرجة واحدة: 10 في الأول و20 في الثاني.

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

أما L=np.insert(A,indices,V,axis=1) فأعطى [[5,10,20,-1,8],[2,10,20,7,-4]] من int64 وبالشكل (2,5). هنا أضيفت القيمتان 10 و20 إلى كل صف، فظهر عمودان جديدان.

نتتبع الصف الثاني لتجنب الاكتفاء بالأول: في S أخذ 20 وحده قبل 7، وفي L أخذ 10 ثم 20 قبل 7. ليست قائمة الفهارس ذات العنصر الواحد طلبًا عامًا لإضافة عنصر واحد إلى كل صف.

عرض المصدر ثلاثة أعمدة. المسار S زاده إلى أربعة، والمسار L إلى خمسة. عدد عناصر V اثنان في الحالتين، وموضع الإدراج واحد؛ اختلاف تنظيم الوسيط obj صاحب اختلاف النتيجة المسجلة.

لا نختصر المقارنة إلى «نجحت العملية». نجح النداءان، لكنهما أنشآ جدولين مختلفَي العرض والقيم. نكتب شكل كل ناتج ونضع علامة على الكتلة التي أضيفت قبل تفسير العمود الجديد.

قارنّا بايتات A وV قبل الاستدعاءات وبعدها فبقيت ثابتة. استعملنا المخرجات الجديدة في المقارنة؛ لم نكتب في أي ناتج أو نفحص ملكية تخزينه.

تنظيم القيم يبدل النتيجتين

أنشأنا Vc=np.array([[10],[20]],dtype=np.int64) بالشكل (2,1). بقيت القيمتان 10 و20، لكن صار لكل منهما صف في مصفوفة عمودية بدل متجه ذي بعد واحد.

شغّلنا np.insert(A,1,Vc,axis=1)، فخرج الجدول [[5,10,20,-1,8],[2,10,20,7,-4]] من int64 وبالشكل (2,5). هذا يوافق L السابق، حيث أضيفت القيمتان داخل كل صف.

وبالفهارس indices مع Vc، خرج [[5,10,-1,8],[2,20,7,-4]] من int64 وبالشكل (2,4). هذا يوافق S السابق. لا نستنتج من عبارة «قيم عمودية» وحدها أن كل طريقة فهرسة ستضيف عمودًا واحدًا.

الفهرسة بعدد تقلل عدد الأبعاد، بينما تسلسل الفهارس يدخل الفهرسة المتقدمة. [2]

لربط الوصف بالشكل، قرأنا A[:,1] فوجدنا [-1,7] بالشكل (2,)، وA[:,indices] فوجدنا [[-1],[7]] بالشكل (2,1). القيم المختارة نفسها؛ نحن نفحص تنظيمها هنا، لا أثر الكتابة عبرها.

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

للتحكم، استعملنا القيمة المفردة 9 بدل V. أعطى الفهرس المفرد والقائمة كلاهما [[5,9,-1,8],[2,9,7,-4]] من int64 وبالشكل (2,4). تغير نوع تنظيم وسيط القيم إلى عدد مفرد.

ثم استعملنا المتجه [10,10] بالشكل (2,). المفرد أعطى [[5,10,-1,8],[2,10,7,-4]] بالشكل (2,4)، والقائمة أعطت [[5,10,10,-1,8],[2,10,10,7,-4]] بالشكل (2,5).

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

أربعة أشكال للإدراج وتحكم مفرد.
شكل القيم العمودي بدّل عرض النتيجتين.

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

يبني مرجع Python كل صف من ثلاثة أجزاء: ما قبل موضع الإدراج، والكتلة المدرجة، وما بقي من الصف الأصلي. يستعمل القوائم والشرائح وضم القوائم، ولا يستدعي insert أو بث NumPy لبناء التوقع.

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

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

للشبكة اخترنا صفين وأعداد أعمدة n من 1 إلى 3. كل خانة من المصدر تختار قيمة من -2 و0 و3، وكل واحدة من قيمتي V تختار من المجموعة نفسها. عدد متجهات القيم 3²=9 لكل جدول.

لكل جدول، استعملنا مواضع الإدراج غير السالبة من صفر إلى n شاملًا. عند n=1 لدينا 3²×9×2=162 حالة، وعند n=2 لدينا 3⁴×9×3=2187، وعند n=3 لدينا 3⁶×9×4=26244؛ المجموع 28593.

لكل حالة ستة فحوص: الفهرس المفرد مع المتجه؛ والقائمة مع المتجه؛ والمفرد مع العمود؛ والقائمة مع العمود؛ وتحكم القيمة المفردة 9 في المسارين؛ وثبات بايتات الجدول والمتجه والعمود وأشكالها. فحوص المخرجات تقارن القيم والنوع والشكل.

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

الحساب (28593+1)×6+3=171567، ومرت جميعها. تحتوي الشبكة مواضع البداية والنهاية أيضًا؛ لم نعرض النتيجة المركزية وحدها ثم نعممها على تلك المواضع دون فحص.

النطاق int64 ثنائي الأبعاد بصفين وأعمدة موجبة من 1 إلى 3، وaxis=1، وفهرس مفرد أو قائمة ذات عنصر واحد، ومتجه قيم بطول 2 أو عمود بالشكل (2,1)، والتحكمين المحددين.

لم نفحص فهارس منطقية أو شرائح أو فهارس متعددة أو مكررة أو سالبة أو خارج المجال، ولا axis=None أو axis=0 أو صفوفًا أخرى أو أبعادًا أعلى أو أنواعًا وتحويلات أخرى.

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

objشكل القيمشكل الناتجالأعمدة المضافة
عدد مفرد(2,)(2,4)1
قائمة بعنصر واحد(2,)(2,5)2
عدد مفرد(2,1)(2,5)2
قائمة بعنصر واحد(2,1)(2,4)1

للتوسع: الفهرس المفرد ومحور الاختيار.

المراجع

  1. NumPy 2.3 — insert
  2. NumPy 2.3 — indexing

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