کتابخانه NumPy پایتون – راهنمای جامع — بخش اول

NumPy یک کتابخانه برای زبان برنامه نویسی پایتون (Python) است. با استفاده از این کتابخانه امکان استفاده از آرایه‌ها و ماتریس‌های بزرگ چند بعدی فراهم می‌شود. هم‌چنین می‌توان از تابع‌های ریاضیاتی سطح بالا بر روی این آرایه‌ها استفاده کرد. پیش از این‌که این آموزش را مطالعه کنید، می‌بایست دست‌کم اندکی با زبان برنامه‌نویسی پایتون آشنایی داشته باشید. همچنین اگر نیاز دارید معلوماتتان را در مورد پایتون یک‌بار یادآوری کنید.

مفاهیم پایه

هدف اصلی NumPy فراهم ساختن امکان کار با آرایه‌های چندبعدی همگن است. این آرایه‌ها جدولی از عناصر (معمولاً اعداد) هستند که همگی از یک نوع می‌باشند و با یک چندتایی، از اعداد صحیح مثبت اندیس‌گذاری می‌شوند. در NumPy ابعاد به نام محور (axe) شناخته می‌شوند. تعداد محورها رتبه (rank) نامیده می‌شود.

برای مثال، مختصات یک نقطه در فضای 3 بعدی [1, 2, 1] یک آرایه با رتبه 1 است زیرا یک محور دارد. این محور طولی به‌اندازه 3 دارد. در مثال زیر آرایه رتبه 2 دارد (2 بعدی است). بعد (محور) نخست طولی به ‌اندازه 2 دارد، بعد دوم طول 3 دارد.

[[ 1., 0., 0.],
[ 0., 1., 2.]]

کلاس آرایه Numpy به‌صورت ndarray نام‌گذاری شده است. همچنین به‌صورت مستعار array نامیده می‌شود. توجه داشته باشید که numpy.array همان کلاس کتابخانه استاندارد پایتون به نام array.array نیست. کتابخانه استاندارد پایتون تنها آرایه‌های تک‌بعدی را مدیریت می‌کند و کاربردهای اندکی دارد. خصوصیات مهم‌تر یک ndarray بدین ترتیب هستند.

ndarray.ndim

تعداد محور (ابعاد) آرایه است. در دنیای پایتون تعداد ابعاد به‌صورت رتبه نامیده می‌شود.

ndarray.shape

ابعاد یک آرایه است. این خصوصیت از یک چندتایی اعداد صحیح تشکیل یافته است که نشان‌دهنده اندازه هر بعد آرایه هستند. برای یک ماتریس با n ردیف و m ستون، شکل (shape) به‌صورت (n,m) خواهد بود. بدین ترتیب طول چندتایی shape برابر با رتبه آرایه یا تعداد ابعاد ndim است.

ndarray.size

تعداد کل عناصر آرایه است. این مقدار برابر با حاصل‌ضرب اجزای shape است.

ndarray.dtype

نوع عناصر یک آرایه را توصیف می‌کند. فرد می‌تواند dtype آرایه را با استفاده از انواع استاندارد پایتون ایجاد یا توصیف کند. به‌علاوه NumPy انواع مخصوص به خود را نیز دارد. برای مثال numpy.int32، numpy.int16 و numpy.float64 نمونه‌هایی از انواع آرایه تعریف شده در NumPy هستند.

ndarray.itemsize

اندازه بایت‌های هر یک از عناصر آرایه است. برای نمونه itemsize یک آرایه از عناصری با نوع float64 برابر با 8 (64/8) است در حالی که itemsize یک آرایه از نوع complex32 برابر با 4 (32/8) است. این مقدار معادل ndarray.dtype.itemsize است.

ndarray.data

این بافر (buffer) حاوی عناصر واقعی آرایه است. به‌طورمعمول ما نیاز نداریم از این خصوصیت استفاده کنیم، زیرا با استفاده از امکان اندیس‌گذاری می‌توانیم به عناصر آرایه دسترسی داشته باشیم.

مثال

>>> from numpy import *
>>> a = arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.ndim
2
>>> a.dtype.name
'int32'
>>> a.itemsize
4
>>> a.size
15
>>> type(a)
numpy.ndarray
>>> b = array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
numpy.ndarray




ایجاد آرایه

چند روش برای ایجاد آرایه وجود دارند. برای مثال، می‌توان با استفاده از تابع array یک آرایه را از فهرست معمولی پایتون یا چندتایی‌ها ایجاد کرد. نوع آرایه حاصل، برابر با نوع عناصر موجود در دنباله‌های تشکیل دهنده آن خواهد بود.

>>> from numpy import *
>>> a = array( [2,3,4] )
>>> a
array([2, 3, 4])
>>> a.dtype
dtype('int32')
>>> b = array([1.2, 3.5, 5.1])
>>> b.dtype
dtype('float64')

یکی از خطاهای رایج در کار کردن با آرایه‌های چندبعدی زمانی رخ می‌دهد که قصد داریم array را با چند آرگومان عددی فراخوانی کنیم، در حالی که باید از فهرست منفردی از اعداد به عنوان آرگومان استفاده کنیم.

>>> a = array(1,2,3,4) # اشتباه
>>> a = array([1,2,3,4]) # صحیح

array دنباله‌ای از دنباله‌ها را به آرایه‌های چندبعدی تبدیل می‌کند، دنباله‌ای از دنباله‌های دنباله‌ها به آرایه‌های سه‌بعدی تبدیل می‌شود و همین‌طور تا آخر.

>>> b = array( [ (1.5,2,3), (4,5,6) ] )
>>> b
array([[ 1.5, 2. , 3. ],
[ 4. , 5. , 6. ]])

نوع آرایه را می‌توان در زمان ایجاد آن به طور صریح تعیین کرد.

>>> c = array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([[ 1.+0.j,  2.+0.j],
       [ 3.+0.j,  4.+0.j]])

معمولاً عناصر یک آرایه از ابتدا مشخص نیستند، اما اندازه آن مشخص است. از این‌رو NumPy چند تابع برای ایجاد آرایه با جایگاه‌های ابتدایی مشخص پیشنهاد می‌کند. بدین ترتیب در ادامه نیازی به بسط آرایه که عملیات پرهزینه‌ای است، وجود نخواهد داشت. تابع zeros یک آرایه با مقادیر تماماً صفر ایجاد می‌کند. تابع ones یک آرایه با مقادیر 1 تولید می‌کند و تابع empty یک آرایه ‌ایجاد می‌کند که محتوای اولیه آن تصادفی است و به وضعیت حافظه بستگی دارد. به طور پیش‌فرض dtype آرایه ‌ایجاد شده، برابر با float64 است.

>>> zeros( (3,4) )
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> ones( (2,3,4), dtype=int16 ) # را هم می‌توان تعیین کرد dtype
array([[[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, 1, 1]],
[[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, 1, 1]]], dtype=int16)
>>> empty( (2,3) )
array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
[ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])

NumPy برای ایجاد دنباله‌هایی از اعداد یک تابع مشابه range ارائه کرده است که به‌جای لیست، یک آرایه برمی‌گرداند.

>>> arange( 10, 30, 5 )
array([10, 15, 20, 25])
>>> arange( 0, 2, 0.3 ) # آرگومان‌های اعشاری می‌پذیرد
array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]

زمانی که arange با آرگومان‌های اعشاری استفاده می‌شود، به دلیل دقت متناهی اعداد اعشاری، عموماً امکان پیش‌بینی تعداد عناصر به دست آمده وجود ندارد. به همین دلیل معمولاً استفاده از تابع linspace که تعداد عناصر مطلوب را نیز به عنوان یک آرگومان می‌گیرد، بهتر است:

>>> linspace( 0, 2, 9 ) # 9 عدد از 0 تا 2
array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
>>> x = linspace( 0, 2*pi, 100 ) # برای تابع ارزیابی در نقاط زیاد مناسب است
>>> f = sin(x)

پرینت کردن آرایه‌ها

زمانی که یک آرایه را پرینت می‌کنید NumPy آن را به صوت یک فهرست تودرتو نمایش می‌دهد که طرح کلی آن به‌صورت زیر است:

  • آخرین محور از چپ به راست پرینت می‌شود.
  • محور ماقبل آخر از بالا به پایین پرینت می‌شود.
  • باقی محورها نیز از بالا به پایین پرینت و هرکدام با یک خط خالی از قبلی جدا می‌شوند.

بدین ترتیب آرایه‌های تک‌بعدی به‌صورت ردیفی، آرایه‌های دوبعدی به‌صورت ماتریس و آرایه‌های سه‌بعدی به‌صورت فهرستی از ماتریس‌ها پرینت می‌شوند.

>>> a = arange(6) # 1d آرایه
>>> print a
[0 1 2 3 4 5]
>>>
>>> b = arange(12).reshape(4,3) # 2d آرایه
>>> print b
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
>>>
>>> c = arange(24).reshape(2,3,4) # 3d آرایه
>>> print c
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]

اگر یک آرایه برای پرینت گرفتن بسیار بزرگ باشد، NumPy به طور خودکار بخش مرکزی آرایه را قطع می‌کند و تنها ابتدا و انتهای آن را نمایش می‌دهد.

>>> print arange(10000)
[ 0 1 2 ..., 9997 9998 9999]
>>>
>>> print arange(10000).reshape(100,100)
[[ 0 1 2 ..., 97 98 99]
[ 100 101 102 ..., 197 198 199]
[ 200 201 202 ..., 297 298 299]
...,
[9700 9701 9702 ..., 9797 9798 9799]
[9800 9801 9802 ..., 9897 9898 9899]
[9900 9901 9902 ..., 9997 9998 9999]

برای این‌که این حالت را غیرفعال کنیم و NumPy کل آرایه را پرینت بگیرد، می‌توانیم با استفاده از گزینه set_printoptions رفتار آن را تغییر دهیم.

>>> set_printoptions(threshold='nan')

پایان بخش یک

لینک بخش دوم به زودی در دسترس قرار خواهد گرفت!


دیدگاه‌ها

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *