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

السؤال

نشر

كيف يمكنك الحصول على مقدار (حجم) المتجه 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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...