اذهب إلى المحتوى

السؤال

نشر

لدي مصفوفتين كالتالي:

a = numpy.array([0,1, 2])
b = numpy.array([3, 4, 5])

كيف يمكنني الحصول على الناتج الديكارتي cartesian product من هذه المصفوفات، لتكون النتيجة كالتالي:

result = array([0, 3], [0, 4], [0, 5], [1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5])

حاولت أن استخدم itertools.product ثم أقوم بتحويل القائمة الناتجة من العملية إلى مصفوفة numpy لكن يبدو أن هذه العملية بطيئة بعض الشيء خصوصًا عند تنفيذها داخل حلقة for 

كيف يمكن تنفيذ هذا الأمر بإستخدام مكتبة Numpy؟

Recommended Posts

  • 2
نشر

إليك طريقة أخرى تعتبر الأسرع :

a = numpy.array([0,1, 2])
b = numpy.array([3, 4, 5])
def cp(*arrays):
    le = len(arrays)
    arr = np.empty([len(a) for a in arrays] + [le], dtype=np.result_type(*arrays))
    for j, x in enumerate(np.ix_(*arrays)):
        arr[...,j] = x
    return arr.reshape(-1, le)
cp(a,b)
'''
array([[0, 3],
       [0, 4],
       [0, 5],
       [1, 3],
       [1, 4],
       [1, 5],
       [2, 3],
       [2, 4],
       [2, 5]])
'''

لاحظ في الصورة أدناه مقارنة بين عدة طرق لتحقيق الجداء الديكارتي (المنحنى ذو اللون البرتقالي يمثل تابعنا والأخضر يمثل استخدام ال transpose)
لاحظ أيضاً أن أسوأ طريقة هي كما أشرت استخدام "itertools"

GF.png

  • 0
نشر

يمكنك ذلك بإستخدام ما يعرف بlist comprehension كما في البرنامج التالي:

import numpy  
x = numpy.array([0,1,2])
y = numpy.array([3,4,5])
numpy.array([[x0, y0] for x0 in x for y0 in y])

لابد أنك لاحظت أن الناتج عبارة عن list والتي يمكن تحويلها لarray فيما بعد بإستخدام numpy.array

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

from sklearn.utils.extmath import cartesian
cartesian((x,y))

الناتج هو عبارة عن حاصل الضرب الديكارتي.

  • 0
نشر

هناك العديد من الطرق لعمل ذلك

def cartesian_product(*arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[...,i] = a
    return arr.reshape(-1, la)

أو

def cartesian_product_transpose(*arrays):
    broadcastable = numpy.ix_(*arrays)
    broadcasted = numpy.broadcast_arrays(*broadcastable)
    rows, cols = numpy.prod(broadcasted[0].shape), len(broadcasted)
    dtype = numpy.result_type(*arrays)

    out = numpy.empty(rows * cols, dtype=dtype)
    start, end = 0, rows
    for a in broadcasted:
        out[start:end] = a.reshape(-1)
        start, end = end, end + rows
    return out.reshape(cols, rows).T

أو

def cartesian_product_simple_transpose(arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([la] + [len(a) for a in arrays], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[i, ...] = a
    return arr.reshape(la, -1).T

أو من أكتوبر 2017 في NumPy أصبح لديها دالة np.stack عامة والتي تأخذ محور كمُدخل، بإستخدامها نستطيع الحصول على ناتج ديكارتي عام بإستخدام تقنية dstack و meshgrid كالآتي

import numpy as np
def cartesian_product(*arrays):
    ndim = len(arrays)
    return np.stack(np.meshgrid(*arrays), axis=-1).reshape(-1, ndim)

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...