English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

وظائف الـ ufunc العامة NumPy

يقدم NumPy نوعين من الأجهزة الأساسية، وهي ndarray وufunc objects. ufunc هو اختصار لـ universal function، مما يعني 'وظيفة عامة'، وهي وظيفة يمكنها تنفيذ عملية على كل عنصر من مصفوفة.
معظم وظائف fuctions تستخدم مستوى لغة C، لذا فإن سرعة حساباتها عالية جدًا.
إضافةً إلى ذلك، fuctions أكثر مرونة من وحدات math. عادة ما تكون المدخلات في وحدات math متقطعة، ولكن الوظائف في NumPy يمكن أن تكون فيectors أو matrices، مما يمكن من تجنب استخدام تعليمات الدوران، وهو أمر مهم جدًا في التعلم الآلي والتعلم العميق.

لماذا نستخدم ufuncs؟

ufunc تُستخدم لتحقيق الت矢量ية في NumPy، وهي أسرع بكثير من التكرار اليدوي للعناصر.
هم يقدمون أيضًا طرقًا مثل الناقص، الجمع، وما إلى ذلك، وهي مفيدة جدًا في الحسابات.
ufuncs تقبل أيضًا أ参数 أخرى، مثل:
where هو مصفوفة منطقية أو شرط، يستخدم لتعريف أين يجب إجراء العمل.
dtype يعرف نوع العنصر الذي سيتم إرجاعه.
القيمة التي يجب نسخها إلى مصفوفة الإخراج.

وظائف عامة مستخدمة بشكل واسع في NumPy
الوظيفةطريقة الاستخدام
sqrt()حساب الجذر التربيعي للسلسلة المعدة
sin()، cos()وظائف الزوايا
abs()حساب القيمة المطلقة للسلسلة المعدة
dot()حسابات المصفوفات
log()، logl()، log2()وظيفة الأس logarithm
exp()وظيفة الأس
cumsum()، cumproduct()الجمع الكلي، الحاصل على الصناديق
sum()جمع سلسلة من البيانات الموسومة
mean()حساب الوسط
median()حساب الوسط الحسابي
std()حساب الانحراف المعياري
var()حساب الانحراف المعياري
corrcoef()حساب معادلة التباين

مقارنة أداء وظائف math و numpy

import time
 import math
 import numpy as np
 x = [i * 0.001 for i in np.arange(1000000)]
 start = time.clock()
 for i, t in enumerate(x):
 x[i] = math.sin(t)
 print("math.sin:", time.clock() - start)
 x = [i * 0.001 for i in np.arange(1000000)]
 x = np.array(x)
 start = time.clock()
 np.sin(x)
 print("numpy.sin:", time.clock() - start)

نتيجة التشغيل:

math.sin: 0.5169950000000005
 numpy.sin: 0.05381199999999886

من هنا يمكن ملاحظة أن numpy.sin أسرع من math.sin حوالي 10 مرات.

تعقيم العمليات

تحويل الجمل التكرارية إلى عمليات متجهة يُدعى بتعقيم العمليات.
بما أن المعالجات الحديثة قد تم تحسينها لتحقيق هذه العمليات، فإن السرعة تكون أسرع.
جمع عناصر كلا القائمتين:
قائمة 1: [1, 2, 3, 4]
قائمة 2: [4, 5, 6, 7]
من الطرق هو مرور كلا القوائم، ثم جمع كل عنصر.

إذا لم يكن هناك ufunc، يمكننا استخدام طريقة zip() المدمجة في بايثون:

x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = []
 for i, j in zip(x, y):
   z.append(i + j)
 print(z)

نتيجة التشغيل:

[5, 7, 9, 11]

في هذا السياق، يحتوي NumPy على ufunc يُدعى add(x, y) وهو يعطي نفس النتيجة، من خلال ufunc، يمكننا استخدام وظيفة add():

import numpy as np
 x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = np.add(x, y)
 print(z)

نتيجة التشغيل:

[5, 7, 9, 11]

مقارنة الدورات بالعمليات المتجهة

استخدام الوظائف المدمجة في مكتبة NumPy لغة بايثون لتحقيق تعقيم العمليات الحسابية، يمكن أن يزيد من سرعة التشغيل بشكل كبير. وظائف المدمجة في مكتبة NumPy تستخدم تعليمات SIMD. مثل استخدام تعقيم العمليات في هذه الحالة، يمكن أن يكون أسرع بكثير من استخدام الدورات. إذا كان يتم استخدام GPU، فإن الأداء سيكون أقوى، ولكن لا يدعم Numpy GPU.
انظر إلى الكود التالي:

import time
 import numpy as np
 x1 = np.random.rand(1000000)
 x2 = np.random.rand(1000000)
 ## استخدام循环 للحصول على نقطة الفرقاء
 tic = time.process_time()
 dot = 0
 for i in range(len(x1)):
 dot += x1[i]*x2[i]
 toc = time.process_time()
 print("dot = " + str(dot) + "\n循环 for ---- وقت الحساب = " + str(1000*(toc - tic)) + "ms")
 ## استخدام وظائف NumPy للحصول على نقطة
 tic = time.process_time()
 dot = 0
 dot = np.dot(x1,x2)
 toc = time.process_time()
 print("dot = " + str(dot) + "\nإصدار Verctor ---- وقت الحساب = " + str(1000*(toc - tic)) + "ms")

نتيجة التشغيل:

 dot = 250215.601995
 循环 for ---- وقت الحساب = 798.3389819999998ms
 dot = 250215.601995
 إصدار Verctor ---- وقت الحساب = 1.885051999999554ms