Fahmy Mostafa نشر 2 يوليو 2021 أرسل تقرير نشر 2 يوليو 2021 لدي مصفوفة بسيطة التالي: x = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) أريد أن أقوم بتحويلها إلى مصفوفة بحجم 5*3 كالتالي: numpy.array([[1, 2, 3, 4, 5] ,[4, 5, 6 ,7, 8], [7, 8, 9, 10, 11]]) حاولت أن أستخدم حلقة for للقيام بهذا الأمر لكن الخطوات لم تكن واضحة بالنسبة لي، كيف يمكنني تطبيق هذا الأمر؟ 1 اقتباس
1 Ali Haidar Ahmad نشر 3 يوليو 2021 أرسل تقرير نشر 3 يوليو 2021 لتشكيل مصفوفة جديدة بطريقة تسمح لك بتحديد الخطوة وال shape، تمنحك Numpy طريقتين رئيسيتين لبناء منظار جديد "new view" لمخزن الذاكرة المؤقت "memory buffer" ، وذلك عن طريق تحديد سمات المصفوفة الأساسية مثل الخطوات "strides" بشكل مباشرة، هاتين الطريقتين هما: as_strided و ndarray. بشكل عام كلاهما يعتبران طرق خطيرة للاستخدام داخل الكود لأنه قد تنتج (((الكثير))) من الأخطاء أثناء استخدامه حتى ولو كنت مبرمجاً محترفاً، لذا لاينصح أبداً بهما إلا للضرورة القصوى. مثلاً في بعض المسائل الصعبة التي قد يسهل حلها عند التلاعب بشكل المصفوفة بهذه الطرق. قبل البدء ماهي ال strides؟ هو مقدار الخطوة، أو هو عدد البايتات اللازمة للانتقال إلى العنصر الثاني من المصفوفة.(ويشار له أيضاً بال axis) طبعاً في حالة المصوفوفة الثنائية نحدد الخطوة الأفقية والخطوة العمودية فمثلاً(16,4) تعني: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) # جهازي بخزن كل قيمة ب4 بايت هذا يعني أنه للانتقال من العنصر 1 إلى 2 نحتاج إلى 4 بايت وللانتقال من بداية البعد الأول [ 0, 1, 2, 3] في المصفوفة إلى البعد الثاني [ 4, 5, 6, 7] نحتاج إلى خطوة مقدارها 16 أي 4*4 أي عدد الأعمدة بحجم كل خطوة as_strided : في اللمثال التالي نقوم بإنشاء view باستخدام هذه الطريقة بشكل مكافئ تماماً ل reshape، ثم سأقوم بإنشاء مايكافئ x.reshape # أنشأنا عرضًا جديدًا لمخزن الذاكرة #x.reshape(3, 4) مايلي يكافئ import numpy as np from numpy.lib.stride_tricks import as_strided x = np.arange(12) #array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) print(x.strides) # أي نحتاج 8 بايتات للانتقال في الذاكرة من العنصر1 إلى 2 as_strided(x, shape=(3, 4), strides=(16, 4))# 16=x.strides*4 '''array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])''' #x.reshape(3, 4) مايلي يكافئ as_strided(x, shape=(3, 4), strides=(4, 16)) # لاحظ كيف أنه من خلال التلاعب بالخطوات يمكنني الحصول على ما أريد القدرات والفائدة الأساسية من as_strided تتجاوز ذلك، فالاستخدام الشائع منها هي ال “sliding window” وهو ما أشرت إليه بسؤالك "إنشاء مصفوفة من x بأبعاد (5,3)" إذاً ماهو ال strides المناسب للقيام بذلك؟ أولاً بالنسبة للأسطر، فالانتقال من عنصر لعنصر يتطلب x.strides أي 4 بايت على جهازي. ثانياً القفز على الأعمدة ( أي للنزول ) كم نحتاج؟ لو ان القيم في الأعمدة متتالية لكنا نحتاج فقط 4 بايت، مثلاً: array([[0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6]]) # ولو كان بالشكل التالي سنحتاج 4*2 array([[0, 1, 2, 3, 4], [2, 3, 4, 5, 6], [4, 5, 6, 7, 8]]) ولو كان بالشكل التالي لحتجنا 4*3 array([[ 0, 1, 2, 3, 4], [ 3, 4, 5, 6, 7], [ 6, 7, 8, 9, 10]]) #لمعرفتها x.strides حجم الخطوة يختلف من جهاز لآخر اسخدم التعليمة x = np.arange(1,12) as_strided(x, shape=(3, 5), strides=(x.strides*3, x.strides)) """ array([[ 1, 2, 3, 4, 5], [ 4, 5, 6, 7, 8], [ 7, 8, 9, 10, 11]]) """ إن الشيء الرائع فيها هو إنه يمكنك تشكيل مصفوفة أكبر حجماً من المصفوفة x ذاتها بدوم أن يتم استهلاك ذاكرة إضافية، أي أننا هنا احتجنا لتمثيل x في الذاكرة 11*4 =44 bytes ثم شكلنا مصفوفة جديدة منها بأبعاد 4,3 أي قد تظن أن الحجم التخزيني سيكون 4*3*4 لكن أنت مخطئ، سيكون 44 بايت أيضاً!! وذلك لأنها تتشارك البيانات. الآن يمكنك تشكيل تابع يعطيك الخرج بالحالة العامة، حيث نمرر له المصفوفة والطول والعرض: def strided_app(a, L, S ): nrows = ((a.size-L)//S)+1 n = a.strides[0] x=np.lib.stride_tricks.as_strided(a, shape=(nrows,L), strides=(S*n,n)) return x strided_app(x,5,3) """ array([[ 0, 1, 2, 3, 4], [ 3, 4, 5, 6, 7], [ 6, 7, 8, 9, 10]]) """ ndarray: يمكنك استخدامها بطريقة مشابهة كالتالي: np.ndarray(buffer=x.data, shape=(3, 5), strides=(12,4), dtype=int) كما يمكنك استخدام طرق عادية لتشكيل المطلوب باستخدام مفهوم ال broadcasting: def broadcasting_app(a, L, S ): nrows = ((a.size-L)//S)+1 x=a[S*np.arange(nrows)[:,None] + np.arange(L)] return x 2 اقتباس
0 Wael Aljamal نشر 2 يوليو 2021 أرسل تقرير نشر 2 يوليو 2021 يمكن استخدام الدالة reshape لإعادة تشكيل المصفوفة: تحجيم المصفوفة للحجم المطلوب، ثم تغيير الأبعاد import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) n = 3 m = 5 x = np.resize(x, n*m) x = x.reshape(n, m) print(x) حيث يمثل الوسيط الأول عدد الأسطر و الثاني عدد الأعمدة وهو المطلوب 1 اقتباس
0 محمد أبو عواد نشر 2 يوليو 2021 أرسل تقرير نشر 2 يوليو 2021 يمكنك فعل ذلك عن طريق Broadcasting ويمكنك فعل ذلك كالتالي def broadcasting_app(a, L, S ): numOfRows = ((a.size-L)//S)+1 return a[S*np.arange(numOfRows)[:,None] + np.arange(L)] حيث ان المعامل a هو المصفوفة التي سوف تمررها والمعامل L هو عدد الأعمدة والمعامل S هو عدد الأسطر 1 اقتباس
0 عبدالله عبدالرحمن11 نشر 2 يوليو 2021 أرسل تقرير نشر 2 يوليو 2021 الطريقة الأولى والتي تعتبر أكثر كفائة بإستخدام NumPy strides كالآتي def strided_app(a, L, S ): nrows = ((a.size-L)//S)+1 n = a.strides[0] return np.lib.stride_tricks.as_strided(a, shape=(nrows,L), strides=(S*n,n)) والطريقة الأخرى عبر إستخدام broadcasting def broadcasting_app(a, L, S ): nrows = ((a.size-L)//S)+1 return a[S*np.arange(nrows)[:,None] + np.arange(L)] 1 اقتباس
0 ريم المهدي نشر 2 يوليو 2021 أرسل تقرير نشر 2 يوليو 2021 ما هو سبب إختيار المصفوفة [4, 5, 6 ,7, 8] ضمن المصفوفات الفرعية؟ العناصر 4و5و7و8 مشتركة بين المصفوفتين الأخريتين،، و لتجد المصفوفات الفرعية المكونة للمصفوفة الرئيسية بإستخدام reshape تحتاج أن يكون عدد الأعمدة * عدد الصفوف = طول المصفوفة و بهذا ستولد المصفوفات المكونة للمصفوفة الرئيسية بدون تكرار في القيم، أما إن كان عدد الأعمدة * عدد الصفوف لا يساوي طول المصفوفة فالدالة ستولد خطأ. ما يمكنني إقتراحه في هذه الحالة هو إستخدام دالة permutation بتحديد القوائم ذات الطول 5 (عدد الأعمدة). import itertools import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) arr = np.array(list(itertools.permutations(set(x),5))) final = [] semifinal = [] for i in arr: semifinal.append(np.array(sorted(i))) final = np.unique(np.array(semifinal),axis=0) بعد إيجاد كل التباديل الممكنة، نقوم بترتيب المصفوفات الداخلية ليسهل عملية إختيار المصفوفات غير المكررة بإستخدام الدالة unique بذلك نكون قد حصلنا على جميع المصفوفات ذات الطول 5 و التي يمكن إيجادها من المصفوفة x. 1 اقتباس
السؤال
Fahmy Mostafa
لدي مصفوفة بسيطة التالي:
أريد أن أقوم بتحويلها إلى مصفوفة بحجم 5*3 كالتالي:
حاولت أن أستخدم حلقة for للقيام بهذا الأمر لكن الخطوات لم تكن واضحة بالنسبة لي، كيف يمكنني تطبيق هذا الأمر؟
5 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.