لا يوجد ترتيب فوري في المصفوفة

4

لا أرى أي أمر فوري في:

import numpy as np
In [143]: np.array([[1,2],[3,4]],order='F')
Out[143]: 
array([[1, 2],
       [3, 4]])

ولكن في ما يلي يعمل:

In [139]: np.reshape(np.arange(9),newshape=(3,3),order='F')
Out[139]: 
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])

إذن ما الذي أفعله خطأ في الأول؟

2 الاجابة

5
افضل جواب

عندما تتصل numpy.array لإنشاء مصفوفة من كائن Python موجود ، سيمنحك كائنًا بأي شكل له كائن Python الأصلي. وبالتالي،

np.array([[1,2],[3,4]], ...)

سأعطيك دائما ،

np.array([[1, 2],
          [3, 4]])

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

يمكنك أن ترى أن المصفوفة مخزنة بالفعل في ترتيب فورتران عندما تقوم بتسويتها باستخدام "K" الترتيب ، الذي يحافظ على الترتيب الأصلي للعناصر:

>>> a = np.array([[1,2],[3,4]], order="F")
>>> a.flatten(order="K")
array([1, 3, 2, 4])

هذا ما يميز فورتران عن ترتيب C: تخطيط الذاكرة. معظم وظائف NumPy لا تجبرك على التفكير في تخطيط الذاكرة ، بدلاً من ذلك ، يتم التعامل مع التخطيطات المختلفة بشفافية.

يبدو أن ما تريده هو التبديل ، وعكس ترتيب المحور. يمكن القيام بذلك ببساطة:

>>> b = numpy.transpose(a)
>>> b
array([[1, 3],
       [2, 4]])

لا يؤدي هذا إلى إنشاء مصفوفة جديدة ، ولكن إلى عرض جديد لنفس المصفوفة:

>>> b.base is a
True

إذا كنت تريد أن تحتوي البيانات على تخطيط الذاكرة 1 2 3 4 وأن يكون لها عرض ترتيب فورتران لذلك [[1 ، 3] ، [2 ، 4]] ، فإن الطريقة الفعالة للقيام بذلك هي تخزين المصفوفة الموجودة مع C قم بترتيبها ثم تبديلها ، مما ينتج عنه مصفوفة ترتيب Fortran مع المحتويات المطلوبة ولا تتطلب نسخًا إضافية.

>>> a = np.array([[1, 2], [3, 4]]).transpose()
>>> a.flatten(order="K")
array([1, 2, 3, 4])
>>> a
array([[1, 3],
       [2, 4]])

إذا قمت بتخزين الأصل بترتيب فورتران ، سينتج عن التبديل ترتيب C ، لذلك لا تريد ذلك (أو ربما كل ما تهتم به هو النقل ، وترتيب الذاكرة ليس مهمًا؟). في كلتا الحالتين ، سيبدو الصفيف نفسه في NumPy.

>>> a = np.array([[1, 2], [3, 4]], order="F").transpose()
>>> a.flatten(order="K")
array([1, 3, 2, 4])
>>> a
array([[1, 3],
       [2, 4]])
:مؤلف
0

الوسيلتان الخاصتان بك لإنشاء الصفيف ثنائي الأبعاد ليسا متكافئين على الإطلاق. في البداية ، حددت بنية الصفيف. في الثانية ، قمت بتشكيل مصفوفة ثم أعدت تشكيلها حسب رغبتك.

>>> np.reshape([1,2,3,4],newshape=(2,2),order='F')
array([[1, 3],
       [2, 4]])

مرة أخرى ، للمقارنة ، حتى إذا طلبت تغيير الشكل وإعادة التنسيق إلى FORTRAN ، فستحصل على الهيكل المحدد:

>>> np.reshape([[1,2],[3,4]],newshape=(2,2),order='F')
array([[1, 2],
       [3, 4]])
:مؤلف
فوق
قائمة طعام