بدأنا بالقيم0x2135 و0x4769 وصفر من <u2. بعد byteswap بقي النوع <u2، لكن القيم صارت0x3521 و0x6947 وصفر. قراءة البايتات المتبدلة بنوع >u2 أعادت القيم الأصلية. سنحفظ البايتات وتفسير النوع معًا.
البايتات وتفسير النوع
تبدل byteswap بايتات عناصر المصفوفة؛ ونستعمل هنا inplace=False. [1]
تغير byteswap ترتيب بايتات البيانات، وتترك تفسير dtype كما هو؛ ويمكن تغيير تفسير الترتيب بواسطة view ونوع جديد. [2] نقرأ أثر الخطوتين منفصلًا، ثم نقرأ اجتماعهما.
العلامة < تعني ترتيب البايتات الصغير، والعلامة > تعني الكبير. [2] نعلن <u2 للمدخل: أعداد غير موقعة من بايتين، مع محور واحد وثلاثة عناصر. لا نستنتج هذا الاختيار من اسم الجهاز وحده.
نكتب قيم المثال بالست عشري أحيانًا لتظهر البايتات، وبالعشري أحيانًا لتظهر الأعداد. 0x2135 يساوي8501، و0x4769 يساوي18281. هذا اختلاف في كتابة العدد نفسه، وليس نداء تحويل بايتات إضافيًا.
كل الأعداد مؤلفة بلا وحدة قياس. لا نقرأ ملفًا أو بروتوكول شبكة، ولا نقرر أن أحد ترتيبَي التخزين صحيح لكل مصدر؛ اخترنا تفسيرًا معلومًا ثم تابعنا نتيجة تغييره.
تبديل وحده يغير الأعداد
في NumPy 2.3.5 وCPython 3.12.14 أنشأنا a=np.array([0x2135,0x4769,0],dtype="<u2"). الشكل (3,)، والقيم [8501,18281,0]. بايتاتها بالترتيب35 21 69 47 00 00، حيث يمثل كل رمزين بايتًا ست عشريًا.
نفذنا b=a.byteswap(inplace=False). رجعت مصفوفة بالشكل (3,) وبنوع <u2 أيضًا، لكن بايتاتها صارت21 35 47 69 00 00. انقلب ترتيب كل زوج بايتات داخل العنصر، ولم تتبادل عناصر المتجه مواضعها.
قرأنا b بالقيم [13601,26951,0]، أي0x3521 و0x6947 وصفر. في قراءة أول زوج بترتيب صغير، البايت21 هو الأقل أهمية، فنحسب0x21+256×0x35=13601؛ هذه قراءة مختلفة عن8501.
الصفر بقي صفرًا؛ بايتاه00 و00 لا يكشفان أثر عكس ترتيبهما. لذلك لا نعتمد على عنصر الصفر وحده لإعلان أن كل القيم حفظت. العنصران الآخران يظهران الفرق مباشرةً في هذه الأعداد.
بقيت a بالقيم والبايتات والنوع والشكل الأصليين بعد النداء. هذا وصف لسلوك inplace=False على المدخل المعلن، ولا يقيس عدد التخصيصات أو إجمالي الذاكرة أو مشاركة التخزين بين الكائنات.
نحفظ نوع b مع بايتاتها، ولا نكتب أن عودة التبديل تحمل >u2 لمجرد أن البايتات تبدلت. في هذا السجل ظل النوع <u2 فعلًا، وقد تغيرت الأعداد مع تبديل البايتات وبقاء هذا التفسير.
نوع جديد وتحكمان للقراءة
تعيد dtype.newbyteorder نوعًا جديدًا بترتيب بايتات مطلوب. [3] نفذنا dt=a.dtype.newbyteorder(">")؛ رجع كائن dtype وصفه >u2، واسمه uint16 وحجم عنصره2. هذا الكائن ليس مصفوفة من قيم المثال.
ثم نفذنا c=b.view(dt). سجلنا النوع >u2 والشكل (3,)، وبايتات21 35 47 69 00 00، والقيم [8501,18281,0]. بايتات c هي بايتات b المتبدلة، لكنها تقرأ هنا بالتفسير الكبير.
في أول زوج، التفسير الكبير يعطي256×0x21+0x35=8501، فتعود قيمة البداية. وكذلك يعود العدد18281 في الزوج الثاني. لم ننفذ تبديلًا ثانيًا كي نعيد البايتات الأصلية؛ تغير تفسير القراءة في هذا المسار.
للتحكم الآخر نفذنا d=a.view(dt) على الأصل مباشرةً، دون تبديل بايتاته. كانت بايتاته35 21 69 47 00 00 كما في a، لكن نوعه >u2 وقيمه [13601,26951,0]. تغيير النوع وحده لم يحفظ قيم الأصل هنا.
إذن c وa تحملان الأعداد نفسها في المثال مع بايتات مختلفة، بينما d وb تحملان الأعداد المتبدلة نفسها مع بايتات مختلفة أيضًا. تساوي القيم لا يعني تساوي التمثيل البايتي، وتساوي البايتات لا يعني تساوي القراءة عند اختلاف النوع.
راجعنا أن بايتات b ونوعها بقيا ثابتين أثناء إنشاء c، وأن a بقيت <u2 ببايتاتها الأصلية أثناء إنشاء d. لم نكتب عبر العروض، ولم نفحص shares_memory أو نستخدم هذه القيم لقياس ملكية التخزين.

الأعداد المحفوظة وحدود الفحص
اخترنا n من33 إلى49، أي17 قيمة. مدخل كل حالة [(n<<8)|0x35,((n+38)<<8)|0x69,0] من <u2. تتغير البايتات العليا للعنصرين الأولين، ويبقى الثالث صفرًا؛ المثال ذو n=33 هو المعروض أعلاه.
لكل مدخل أربعة نداءات: byteswap مع False، وdtype.newbyteorder مع >، وview على الناتج المتبدل، وview على الأصل. العدد17×4=68 نداءً، وجميعها رجعت بنجاح دون سجلات خطأ.
ثلاث عودات لكل حالة مصفوفات من ثلاثة عناصر:17×3=51 مصفوفة عائدة في السجلات، و51×3=153 قيمة عددية محفوظة. أما17 عودة dtype فهي كائنات وصف نوع، ولا نعد حجم عنصرها2 ضمن153 قيمة.
لا نسمي51 سجل عودة51 تخصيصًا مستقلًا، ولا153 عنصرًا153 قيمة متميزة. سجلنا النتائج بأسمائها وقيمها وبايتاتها وأشكالها وأنواعها، ثم فصلنا تعداد العودات عن أي تقدير ذاكرة لم نقسه.
بنى مرجع Python بايتات المصدر بـstruct، ثم عكس كل زوج منها. فك البايتات بالتفسير الصغير أعطى توقع التبديل وحده، وبالكبير أعطى توقع القراءة المستعادة؛ وفك الأصل بالكبير أعطى تحكم النوع وحده. كل المتوقع بُني قبل استيراد NumPy.
وافقت النتائج المرجع، واختلفت بايتات المدخلات السبعة عشر، وبقي كل مصدر ثابتًا. لا يستعمل المرجع تبديل NumPy أوview أوdtype لتوليد الأعداد التي نقارن بها الناتج.
النطاق uint16 وهذه المتجهات والأنواع والإعدادات. لم نفحص inplace=True أوتبديلًا ثانيًا أوالكتابة أوأنواعًا مركبة أوموقعة أوعائمة أوobject أونصوصًا أوأشكالًا أخرى أوفئات مشتقة أوastype أوملفات أوأداءً أوإصدارًا آخر.
| Own array | dtype | Values (hex) |
|---|---|---|
| Original | <u2 | 2135 / 4769 / 0 |
| Swap only | <u2 | 3521 / 6947 / 0 |
| Swap + big view | >u2 | 2135 / 4769 / 0 |
| Big view only | >u2 | 3521 / 6947 / 0 |
للتوسع: العرض والتخزين.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
