تقنية

getfield: هل offset رقم عنصر؟

ثلاث مجموعات بايتات والعمود الثاني.
offset=1 تختار [17,21,31].

إزاحة getfield تُقاس بالبايت داخل العنصر. [1] نؤلف ثلاثة عناصر ونتتبع البايت المختار وأثر الكتابة فيه.

أعلن البايتات والنوع قبل القراءة

توثق getfield عرضًا من بيانات المصفوفة بنوع مطلوب وإزاحة بالبايت؛ يجب أن يتسع نوع العرض داخل نوع الأصل. [1] لا نفسر offset على أنها فهرس العنصر في المصفوفة.

نستعمل NumPy 2.3.5. نختار ثلاث مجموعات مؤلفة: [3,17,9,5] و[8,21,4,6] و[7,31,2,1]. الأعداد بلا وحدة قياس، وكل مجموعة تصف أربعة بايتات بالترتيب المخزن الذي نريده.

لكل مجموعة b نحسب عدد Python بالتعبير sum(b[j]*256**j for j in range(4)). ثم نبني a=np.array(words,dtype="<u4"). العلامة < تعلن أن البايت الأقل أهمية يأتي أولًا؛ لا نترك هذا الاختيار ضمنيًا.

قرأنا قيم الأصل [84480259,100930824,16916231]، وشكله (3,)، وحجم عنصره أربعة بايتات وخطوته (4,). تحققنا أن بايتاته الاثني عشر تطابق المجموعات المؤلفة قبل استخراج العرض.

قارن الأعمدة داخل العناصر

استدعينا y=a.getfield(np.uint8,offset=1). قرأنا y=[17,21,31]، ونوعه uint8 وشكله (3,). الأعداد الثلاثة هي العمود الثاني من مجموعاتنا، لا عدد واحد مأخوذ من فهرس الأصل 1.

أعطت الإزاحة 0 القيم [3,8,7]، والإزاحة 2 القيم [9,4,2]، والإزاحة 3 القيم [5,6,1]. تغيير الإزاحة اختار عمود بايتات آخر داخل العناصر الثلاثة؛ لم يغير عدد عناصر العرض.

حجم عنصر y بايت واحد، لكن y.strides=(4,). بين البايت المختار في عنصر والبايت المختار في العنصر التالي أربعة بايتات في هذا الأصل. ليست القيم الثلاثة كتلة متتابعة بخطوة بايت واحد.

تعرف الوثائق strides بأنها خطوات بالبايت على الأبعاد. [2] هنا نفرق بين خطوة الانتقال إلى العنصر التالي وبين إزاحة البداية داخل كل عنصر.

في PyArray_GetField المقروءة من مصدر الإصدار 2.3.5، يستعمل إنشاء العرض أبعاد الأصل وخطواته مع إضافة offset إلى بداية البيانات. [3] قرأنا الدالة وغلاف array_getfield كاملين، دون مطابقة المصدر بملف NumPy الثنائي المثبت.

اكتب في العرض ثم افحص بايتات الأصل

قبل الكتابة أعطى np.shares_memory(a,y) النتيجة True، وكان علم OWNDATA للعرض False. بقيت بايتات الأصل ثابتة خلال استدعاءات استخراج الأعمدة الأربعة.

نفذنا y[0]=200. أصبحت مجموعة العنصر الأول [3,200,9,5] بدل [3,17,9,5]. بقيت المجموعتان [8,21,4,6] و[7,31,2,1] كما هما.

حسب مرجع Python العدد الجديد: 3+200*256+9*256**2+5*256**3=84527107. قرأنا الأصل [84527107,100930824,16916231]، وتحققنا من بايتاته بعد الكتابة.

صار عرض الإزاحة 1 هو [200,21,31]. بقيت عروض الإزاحات 0 و2 و3 بالقيم السابقة؛ احتفظنا بالعروض نفسها لقراءة الأثر، ولم نستخرج عروضًا جديدة بعد الكتابة.

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

بايتات العنصر الأول قبل الكتابة وبعدها.
y[0]=200 تغير بايتًا واحدًا.

اختبر حد الإزاحة وحدد نطاق الدليل

جرّبنا a.getfield(np.uint8,offset=4)، فرفعت ValueError وبقي الأصل ثابتًا قبل الكتابة. يتطلب بايت البداية 4 مع حجم العرض 1 خمسة بايتات، بينما حجم عنصر الأصل أربعة فقط.

أضفنا ثلاث مجموعات كلها صفر، وثلاث مجموعات كلها 5، ثم التركيبات الستة عشر من {2,7} في بايتات المجموعة الأولى، مع تثبيت المجموعتين الأخريين. مع المثال أصبح لدينا 19 مدخلًا مختلفًا.

أنشأنا أصلًا جديدًا لكل مدخل. استدعينا getfield للإزاحات 0 و1 و2 و3 و4: الحساب 19×5=95. حصلنا على 76 عرضًا ناجحًا و19 حالة ValueError.

نفذنا 76 فحص مشاركة مساعدًا و19 كتابة خارج عد استدعاءات getfield. قيمة الكتابة في الحالة ذات الرقم c هي 200+c؛ جميعها ضمن مجال البايت. حفظنا 456 قيمة عرض و114 قيمة أصل قبل الكتابة وبعدها.

مرجعنا مستقل: الأعمدة من المجموعات المؤلفة، والأعداد من مجموع قوى 256. بعد الكتابة نستبدل البايت الثاني في المجموعة الأولى وحده؛ لا نجعل مخرج NumPy مرجعًا لنفسه.

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

offset قبل الكتابةقيم العرض uint8الخطوة بالبايت
0[3,8,7]4
1[17,21,31]4
2[9,4,2]4
3[5,6,1]4

للتوسع: وحدة إزاحة النص.

المراجع

  1. NumPy ndarray getfield
  2. NumPy ndarray strides
  3. NumPy versioned getfield C source

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