diff يبقي فروق المدخلات غير الموقعة غير موقعة. [1] لذلك نحدد نوع الحساب قبل تفسير العدد الناتج بوصفه زيادة أو نقصانًا.
حدد فرق القيم الذي تريده
نختار ثلاث قيم صحيحة مؤلفة x=[8,3,10]، ونفترض أنها مخزنة في نوع uint8. لا تمثل هذه الأعداد قياسًا لجهاز أو تجربة. نريد الفرق العددي بين كل مشاهدة والتي تليها، مع الاحتفاظ بعلامة الانخفاض.
الفرق الأول في diff هو a[i+1]−a[i]. دون إضافات طرفية، ينقص طول محور الفرق بواحد. [1]
في المثال، الانتقال من 8 إلى 3 يعطي 3−8=−5، والانتقال من 3 إلى 10 يعطي 10−3=7. إذن الفروقان الرياضيان [-5,7]. عدد الفروق 2 لأن لدينا انتقالين بين ثلاث قيم.
الفرق يصف الانتقال بين قيمتين، فلا ننسب الفروق إلى ثلاث مشاهدات مستقلة. نثبت جهة الطرح: التالية ناقص السابقة. عكس الجهة يعطي [5,-7]، وهو جواب لمقارنة معكوسة.
لا نحسب معدلًا في هذا المثال. لم نعلن فواصل زمنية أو مكانية، ولم نقسم فرقًا على فاصل. سنركز على قدرة نوع الحساب على حفظ الفرق العددي الذي كتبناه، ثم نقارن ما يحدث إذا غيرنا النوع في وقتين مختلفين.
افهم القيمة الملفوفة في ثمانية بتات
uint8 نوع غير موقع من ثمانية بتات، مجاله 0 إلى 255. [2] نحتاج إذن تفسيرًا للفرق −5 الذي يقع خارج هذا المجال.
تظل نتائج diff للمصفوفات الصحيحة غير الموقعة غير موقعة؛ يوصي التوثيق بالتحويل إلى نوع صحيح أوسع أولًا عند الحاجة. [1]
نحسب نموذج الثمانية بتات مستقلًا: نحتفظ بباقي الفرق عند القسمة على 256، ضمن 0 إلى 255. للفرق −5 نضيف 256 مرة، فنحصل على 251. والفرق 7 داخل المجال فيبقى 7. قائمة نموذجنا هي [251,7].
نستطيع مراجعة البتات في الفرق الأول: 3 يكتب 00000011، و8 يكتب 00001000. الطرح مع الاحتفاظ بثماني خانات يعطي 11111011. أوزانه غير الموقعة مجموعها 128+64+32+16+8+2+1=251.
لا يعني هذا أن 3−8 صار يساوي 251 في حساب الأعداد الصحيحة. الفرق الرياضي ما زال −5. الرقم 251 هو قراءة النمط المحتفظ به في نموذج غير موقع محدود العرض. لا نقرأه بوصفه مقدار الزيادة بين المشاهدتين.
هناك غموض إذا لم نملك الأصل: الانتقال من 0 إلى 251 يعطي فرقًا رياضيًا 251، والانتقال من 8 إلى 3 يعطي −5. كلاهما يعطي الباقي 251 في النموذج. لذلك لا تحدد القيمة الملفوفة وحدها علامة الفرق الأصلي.
قارن التحويل قبل الطرح وبعده
نقارن مسارين بمدخل واحد. في الأول نجري الحساب ذي الثمانية بتات، فنحصل على [251,7]، ثم نوسع الأعداد إلى نوع بإشارة قادر على تمثيلها. القيمتان 251 و7 تدخلان النوع الأوسع كما هما.
النتيجة في هذا المسار تبقى [251,7]. التحويل العددي لا يسأل أي انتقال أنتج الرقم 251؛ قد يكون ناتج زيادة 251 أو انخفاض 5 في النموذج السابق. مجرد وجود إشارة في النوع الجديد لا يغير 251 إلى عدد سالب.
في المسار الثاني نوسع المدخلات [8,3,10] أولًا مع حفظ قيمها، ثم نطرح في المجال الأوسع. لدينا 3−8=−5، و10−3=7؛ فنحصل على [-5,7]. لم تتغير المشاهدات الأصلية، لكن مجال العملية صار قادرًا على حمل السالب.
يوضح التوثيق التحويل قبل diff باستخدام astype إلى int16. [1]
مثلًا، لو كانت a مصفوفة المثال بنوع uint8، فاختيار diff(a.astype(int16)) يضع التحويل قبل الطرح، بينما diff(a).astype(int16) يضعه بعده؛ نفهم ذلك بترتيب العمليتين. هذه مقارنة صيغ، وليست سجل تشغيل للمكتبة.
لا نستبدل التحويل العددي بإعادة تفسير نمط البتات بنوع آخر. سؤالنا هو حفظ قيم المدخلات ثم حساب الفرق، وليس تغيير معنى البتات نفسها. يبقى الأصل [8,3,10] المرجع الذي يسمح لنا بإعادة الحساب الصحيح إذا احتفظنا به.

اختر مجالًا يتسع لكل الفروق
int16 نوع صحيح بإشارة من ستة عشر بتًا، مجاله −32768 إلى 32767. [2]
لكل قيمتين a وb بين 0 و255، أصغر فرق b−a يقع عند b=0 وa=255، فيساوي −255. أكبر فرق يقع عند b=255 وa=0، فيساوي 255. إذن كل فرق أول يقع في المجال المغلق من −255 إلى 255.
هذا المجال كله داخل مجال int16 المذكور. كذلك المدخلات من 0 إلى 255 داخله. لذلك في نطاقنا يكفي التحويل إلى int16 قبل الطرح لحفظ قيم المدخلات والفروق الرياضية، بما فيها الحالات الطرفية 0−255 و255−0.
int8 مجاله −128 إلى 127. [2] لا يتسع لمدخل أو فرق قيمته 255؛ نحتاج عرضًا كافيًا، لا مجرد نوع بإشارة.
الضمان هنا خاص بالفروق الأولى لمدخلات uint8، من دون prepend أو append. إذا كررنا أخذ الفروق، أصبحت المدخلات الجديدة فروقًا لا مشاهدات بين 0 و255؛ علينا اشتقاق حدود جديدة. ونراجع المجال أيضًا إذا تغير نوع المدخلات أو أضيفت قيم طرفية.
لم ننفذ NumPy. حسبنا أمثلة صحيحة، وقارنا الطرح ذي الاستلاف في ثمانية بتات بباقي الفرق لكل زوج من قيم 0 إلى 255. الاختبار يراجع نموذج الحساب المحدد؛ لا يثبت قواعد تحويل لجميع الأنواع أو إصدارات التشغيل.
| المسار في المثال | قيم المدخلات قبل الطرح | الفروق المحفوظة |
|---|---|---|
| حساب رياضي بإشارة | [8,3,10] | [-5,7] |
| طرح uint8 ثم توسيع النتيجة | [8,3,10] | [251,7] |
| توسيع المدخلات ثم الطرح | [8,3,10] | [-5,7] |
للتوسع: ترتيب المشاهدات لحساب الوسيط.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
