• 0

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

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

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

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

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

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 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
1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 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

 

انشر على الشّبكات الاجتماعية


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

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن