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

الحصول على الناتج الديكارتي في numpy

Fahmy Mostafa

السؤال

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

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

يمكنك استخدام الدالة transpose بهذا الشكل

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

numpy.transpose([numpy.tile(a, len(b)), numpy.repeat(b, len(a))])

سوف تكون النتيحة كالتالي

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

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...