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

كيف تحصل على مقدار المتجه في Numpy؟

Amer Abdallah

السؤال

كيف يمكنك الحصول على مقدار (حجم) المتجه magnitude  (مصفوفة أحادية البعد 1D) في Numpy؟

حاولت أن أقوم بالأمر بنفسي وكتبت الكود التالي:

def magnitude(x): 
    return math.sqrt(sum(i**2 for i in x))

الكود السابق يعمل بدون مشكلة، لكني أتسأل هل توجد دالة جاهزة في Numpy تقوم بهذا الأمر بدلًا من إستعمال مكتبات مثل math؟

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

Recommended Posts

  • 1

يمكنك القيام بحساب طويلة متجه بعدة طرق. أولها من خلال التابع numpy.linalg.norm  بالشكل التالي:

import numpy as np
x = np.array([1,2,3,4])
np.linalg.norm(x)
# 5.477225575051661

حيث أن التابع np.linalg.norm(x) يقوم بحساب الطويلة للشعاع. أو يمكنك تحقيق ذلك بشكل يدوي من خلال استخدم التابع dot و sqrt كالتالي حيث أن عملية إيجاد الطويلة لمتجه هو تربيع القيم ثم حساب الجذر التربيعي وبالتالي نستخدم عملية الضرب x.dot(x) لتقوم بعملية ضرب عناصر الشعاع x ببعضها ثم حساب جذر المجموع الناتج:

m = np.sqrt(x.dot(x))
# 5.477225575051661
# بحيث:
# x.dot(x)=30
# 1*1+2*2+3*3+4*4=30
# 30^1/2=5.477

أو يمكنك الاعتماد على مكتبة einsum لتنفيذ الجداء :

np.sqrt(np.einsum('...i,...i', x, x))
# 5.477225575051661

أو:

from numpy.core.umath_tests import inner1d
np.sqrt(inner1d(x,x))

أو من خلال مكتبة vg استخدم التابع :

import vg
vg.magnitude(x)
#5.477225575051661

لكن عليك أولاً أن تقوم بتحميلها:

pip install vg

للمقارنة:

%timeit vg.magnitude(x)
%timeit np.sqrt(inner1d(x,x))
%timeit np.sqrt(np.einsum('...i,...i', x, x))
%timeit np.sqrt(x.dot(x))
%timeit np.linalg.norm(x)
"""
The slowest run took 142.37 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 8.71 µs per loop
The slowest run took 8.71 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 5.11 µs per loop
The slowest run took 6.30 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 8.37 µs per loop
The slowest run took 10.48 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 4.6 µs per loop
The slowest run took 17.93 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 5: 8.51 µs per loop
"""

 

تم التعديل في بواسطة Ali Haidar Ahmad
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

الوظيفة التي تبحث عنها هي numpy.linalg.norm ، أعتقد أنه يجب أن تكون في قاعدة numpy كخاصية لمصفوفة array مثلاً x.norm() .

import numpy as np
x = np.array([1,2,3,4,5])
np.linalg.norm(x)

يمكنك أيضًا تغذية ord اختياري من أجل ترتيب norm ال nth الذي تريده ، لنفترض أنك أردت 1-norm:

np.linalg.norm(x,ord=1)

وهكذا

إذا كنت قلقاً بخصوص السرعة فيجب عليك استخدام

mag = np.sqrt(x.dot(x))

وهذا اختبار للقياس

>>> import timeit
>>> timeit.timeit('np.linalg.norm(x)', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0450878
>>> timeit.timeit('np.sqrt(x.dot(x))', setup='import numpy as np; x = np.arange(100)', number=1000)
0.0181372

اما من أجل تحسين السرعة الحقيقي فيأتي عندما تأخذ ال norm للعديد من ال vectors.

بإستخدام دوال numpy لا يتطلب استخدام حلقات for ، علي سبيل المثال:

In [1]: import numpy as np

In [2]: a = np.arange(1200.0).reshape((-1,3))

In [3]: %timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 4.23 ms per loop

In [4]: %timeit np.sqrt((a*a).sum(axis=1))
100000 loops, best of 3: 18.9 us per loop

In [5]: np.allclose([np.linalg.norm(x) for x in a],np.sqrt((a*a).sum(axis=1)))
Out[5]: True

 

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

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...