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

۱۱۳۳ بازدید
آخرین به‌روزرسانی: ۰۸ مهر ۱۴۰۲
زمان مطالعه: ۱۱ دقیقه
کتابخانه NumPy پایتون – راهنمای جامع — بخش دوم

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

قواعد انتشار (Broadcasting)

قواعد انتشار به تابع‌های سراسری اجازه می‌دهد که به یک روش منطقی با ورودی‌ها کار کنند و لازم نیست که شکل یکسانی داشته باشند. قاعده نخست انتشار این است که اگر همه ورودی‌های آرایه ابعاد یکسانی نداشته باشند، یک «1» مکرراً به شکل‌های آرایه‌ای کوچک‌تر اضافه می‌شود تا جایی که آرایه مذکور به تعداد ابعاد مشابه برسد. قاعده دوم انتشار تضمین می‌کند که آرایه‌هایی که در یک بعد خاص، ابعادی به طول 1 دارند طوری عمل می‌کنند که گویی در آن بعد، اندازه‌ای بزرگ‌تر دارند. مقدار عنصر آرایه در آن بعد، برابر با مقدار عنصر در راستای همان بعد در آرایه «انتشار» در نظر گرفته می‌شود.

اندیس‌گذاری زیبا و ترفندهای اندیس‌گذاری

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

اندیس‌گذاری با آرایه‌ها و اندیس‌ها

1>>> a = arange(12)**2 # نخستین 12 عدد مربع
2>>> i = array( [ 1,1,3,8,5 ] ) # آرایه‌ای از اندیس‌ها
3>>> a[i] # i در موقعیت‌های a عناصر
4array([ 1, 1, 9, 64, 25])
5>>>
6>>> j = array( [ [ 3, 4], [ 9, 7 ] ] ) # یک آرایه دوبعدی از اندیس‌ها
7>>> a[j] # jهمان شکل
8array([[ 9, 16],
9[81, 49]])

زمانی که آرایه اندیس‌گذاری شده a چندبعدی باشد، منظور از یک آرایه منفرد از اندیس‌ها، در واقع بعد نخست a است. مثال زیر با تبدیل کردن یک تصویر از برچسب‌ها به یک تصویر رنگی با استفاده از یک پالت این رفتار را نشان می‌دهد.

1>>> palette = array( [ [0,0,0], # مشکی
2... [255,0,0], # قرمز
3... [0,255,0], # سبز
4... [0,0,255], # آبی
5... [255,255,255] ] ) # سفید
6>>> image = array( [ [ 0, 1, 2, 0 ], # هر مقدار متناظر با یک رنگ در پالت است
7... [ 0, 3, 4, 0 ] ] )
8>>> palette[image] # (2,4,3) تصویر رنگی
9array([[[ 0, 0, 0],
10[255, 0, 0],
11[ 0, 255, 0],
12[ 0, 0, 0]],
13[[ 0, 0, 0],
14[ 0, 0, 255],
15[255, 255, 255],
16[ 0, 0, 0]]])

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

1>>> a = arange(12).reshape(3,4)
2>>> a
3array([[ 0, 1, 2, 3],
4[ 4, 5, 6, 7],
5[ 8, 9, 10, 11]])
6>>> i = array( [ [0,1], # aاندیس‌های بعد نخست
7... [1,2] ] )
8>>> j = array( [ [2,1], # اندیس‌های بعد دوم
9... [3,3] ] )
10>>>
11>>> a[i,j] # باید ابعاد یکسانی داشته باشندj و i
12array([[ 2, 5],
13[ 7, 11]])
14>>>
15>>> a[i,2]
16array([[ 2, 6],
17[ 6, 10]])
18>>>
19>>> a[:,j] # i.e., a[: , j]
20array([[[ 2, 1],
21[ 3, 3]],
22[[ 6, 5],
23[ 7, 7]],
24[[10, 9],
25[11, 11]]])

به طور طبیعی می‌توان i و j را در یک دنباله (مثلاً یک فهرست) قرار داد و سپس با استفاده از فهرست اندیس‌گذاری کرد.

1>>> l = [i,j]
2>>> a[l] # a[i,j]معادل
3array([[ 2, 5],
4[ 7, 11]])

ولی این کار را با قرار دادن i و j در یک آرایه نمی‌توان انجام داد، زیرا آرایه به عنوان اندیس‌گذاری بعد نخست a تفسیر می‌شود.

1>>> s = array( [i,j] )
2>>> a[s] # همان چیزی که می‌خواستیم
3Traceback (most recent call last):
4File "<stdin>", line 1, in ?
5IndexError: index (3) out of range (0<=index<=2) in dimension 0
6>>>
7>>> a[tuple(s)] # a[i,j]همانند
8array([[ 2, 5],
9[ 7, 11]])

استفاده رایج دیگر از اندیس‌گذاری آرایه‌ها، جستجوی مقدار بیشینه سری‌های وابسته به زمان است:

1>>> time = linspace(20, 145, 5) # مقیاس زمانی
2>>> data = sin(arange(20)).reshape(5,4) # 4 سری وابسته به زمان
3>>> time
4array([ 20. , 51.25, 82.5 , 113.75, 145. ])
5>>> data
6array([[ 0. , 0.84147098, 0.90929743, 0.14112001],
7[-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ],
8[ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
9[-0.53657292, 0.42016704, 0.99060736, 0.65028784],
10[-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
11>>>
12>>> ind = data.argmax(axis=0) # اندیس ماتریس برای هر سری
13>>> ind
14array([2, 0, 3, 1])
15>>>
16>>> time_max = time[ ind] # maxima زمان متناظر با هر
17>>>
18>>> data_max = data[ind, xrange(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
19>>>
20>>> time_max
21array([ 82.5 , 20. , 113.75, 51.25])
22>>> data_max
23array([ 0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
24>>>
25>>> all(data_max == data.max(axis=0))
26True

همچنین می‌توان از اندیس‌گذاری آرایه‌ها به عنوان هدفی برای انتساب مقادیر به آن‌ها استفاده کرد:

1>>> a = arange(5)
2>>> a
3array([0, 1, 2, 3, 4])
4>>> a[[1,3,4]] = 0
5>>> a
6array([0, 0, 2, 0, 0])

بااین‌حال وقتی یک فهرست از اندیس‌ها شامل موارد تکراری باشد، این انتساب چند بار رخ می‌دهد و بخشی از مقادیر حذف می‌شوند:

1>>> a = arange(5)
2>>> a[[0,0,2]]=[1,2,3]
3>>> a
4array([2, 1, 3, 3, 4])

منطق این کار مشخص است اما ابتدا بررسی کنید که آیا می‌خواهید از سازه =+ پایتون استفاده کنید یا نه، چون ممکن است آن چیزی نباشد که انتظار دارید:

1>>> a = arange(5)
2>>> a[[0,0,2]]+=1
3>>> a
4array([1, 1, 3, 3, 4])

با این‌که مقدار 0 دو بار در فهرست اندیس‌ها ظاهر شده است اما عنصر 0-ام تنها یک عنصر افزایش یافته است. این حالت به این دلیل رخ داده است که پایتون الزام می‌کند «a+=1» معادل «a=a+1» محاسبه شود.

اندیس‌گذاری با استفاده از آرایه‌های بولی

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

1>>> a = arange(12).reshape(3,4)
2>>> b = a > 4
3>>> b #است a بولی و با شکل b
4array([[False, False, False, False],
5[False, True, True, True],
6[True, True, True, True]], dtype=bool)
7>>> a[b] # آرایه 1 بعدی با عناصر منتخب
8array([ 5, 6, 7, 8, 9, 10, 11])

این خصوصیت می‌تواند در زمان انتساب مقادیر بسیار مفید باشد:

1>>> a[b] = 0 # که بالاتر از 4 هستند به 0 تبدیل می‌شوند'a' همه عناصر
2>>> a
3array([[0, 1, 2, 3],
4[4, 0, 0, 0],
5[0, 0, 0, 0]])

این روش دوم اندیس‌گذاری با عبارت‌های بولی به روش اندیس‌گذاری با اعداد صحیح شباهت بیشتری دارد، چون برای هر بعد آرایه، یک آرایه بولی 1 بعدی اختصاص می‌دهیم و تکه‌هایی که می‌خواهیم را از میان آن‌ها انتخاب می‌کنیم.

1>>> a = arange(12).reshape(3,4)
2>>> b1 = array([False,True,True]) # انتخاب بعد نخست
3>>> b2 = array([True,False,True,False]) # انتخاب بعد دوم
4>>>
5>>> a[b1,:] # انتخاب ردیف‌ها
6array([[ 4, 5, 6, 7],
7[ 8, 9, 10, 11]])
8>>>
9>>> a[b1] # همان
10array([[ 4, 5, 6, 7],
11[ 8, 9, 10, 11]])
12>>>
13>>> a[:,b2] # انتخاب ستون‌ها
14array([[ 0, 2],
15[ 4, 6],
16[ 8, 10]])
17>>>
18>>> a[b1,b2] # یک کار عجیب!
19array([ 4, 10])

توجه کنید که طول آرایه بولی تک‌بعدی باید با طول ابعادی که می‌خواهیم قطعه‌بندی کنیم هماهنگ باشد.

تابع  ()_ix

تابع ()_ix را می‌توان برای ترکیب بردارهای مختلف استفاده کرد به طوری که برای هر n-تایی یک آرایه به دست آورد. برای مثال اگر بخواهیم همه مقادیر a+b*c را برای همه چندتایی‌های به دست آمده از هر بردار a، b و c به دست آوریم، می‌توانیم از تابع ()_ix استفاده کنیم.

1>>> a = array([2,3,4,5])
2>>> b = array([8,5,4])
3>>> c = array([5,4,6,8,3])
4>>> ax,bx,cx = ix_(a,b,c)
5>>> ax
6array([[[2]],
7[[3]],
8[[4]],
9[[5]]])
10>>> bx
11array([[[8],
12[5],
13[4]]])
14>>> cx
15array([[[5, 4, 6, 8, 3]]])
16>>> ax.shape, bx.shape, cx.shape
17((4, 1, 1), (1, 3, 1), (1, 1, 5))
18>>> result = ax+bx*cx
19>>> result
20array([[[42, 34, 50, 66, 26],
21[27, 22, 32, 42, 17],
22[22, 18, 26, 34, 14]],
23[[43, 35, 51, 67, 27],
24[28, 23, 33, 43, 18],
25[23, 19, 27, 35, 15]],
26[[44, 36, 52, 68, 28],
27[29, 24, 34, 44, 19],
28[24, 20, 28, 36, 16]],
29[[45, 37, 53, 69, 29],
30[30, 25, 35, 45, 20],
31[25, 21, 29, 37, 17]]])
32>>> result[3,2,4]
3317
34>>> a[3]+b[2]*c[4]
3517

همچنین می‌توان از تابع reduce استفاده کرد:

1def ufunc_reduce(ufct, *vectors):
2vs = ix_(*vectors)
3r = ufct.identity
4for v in vs:
5r = ufct(r,v)
6return r

و سپس از آن به‌صورت زیر استفاده کرد:

1>>> ufunc_reduce(add,a,b,c)
2array([[[15, 14, 16, 18, 13],
3[12, 11, 13, 15, 10],
4[11, 10, 12, 14, 9]],
5[[16, 15, 17, 19, 14],
6[13, 12, 14, 16, 11],
7[12, 11, 13, 15, 10]],
8[[17, 16, 18, 20, 15],
9[14, 13, 15, 17, 12],
10[13, 12, 14, 16, 11]],
11[[18, 17, 19, 21, 16],
12[15, 14, 16, 18, 13],
13[14, 13, 15, 17, 12]]])

مزیت این نسخه از تابع reduce در مقایسه با نسخه معمولی ufanc.reduce این است که در آن از قواعد انتشار استفاده شده است تا از ایجاد یک آرایه‌ی آرگومان در خروجی که اندازه‌ای چند برابر بردارها دارد، اجتناب شود.

جبر خطی

عملیات‌های ساده بر روی آرایه

در ادامه برخی مثال‌ها برای آشنایی با عملیات‌های ساده جبر خطی بر روی آرایه‌ها ارائه شده‌اند که برای کاربری در سطح متوسط نیاز به توضیح چندانی ندارند:

1>>> from numpy import *
2>>> from numpy.linalg import *
3>>> a = array([[1.0, 2.0], [3.0, 4.0]])
4>>> print a
5[[ 1. 2.]
6[ 3. 4.]]
7>>> a.transpose()
8array([[ 1., 3.],
9[ 2., 4.]])
10>>> inv(a)
11array([[-2. , 1. ],
12[ 1.5, -0.5]])
13>>> u = eye(2) # واحد 2x2 ماتریس; "I"معادل "eye"
14>>> u
15array([[ 1., 0.],
16[ 0., 1.]])
17>>> j = array([[0.0, -1.0], [1.0, 0.0]])
18>>> dot (j, j) # ضرب ماتریس
19array([[-1., 0.],
20[ 0., -1.]])
21>>> trace(u) # trace
222.0
23>>> y = array([[5.], [7.]])
24>>> solve(a, y)
25array([[-3.],
26[ 4.]])
27>>> eig(j)
28(array([ 0.+1.j, 0.-1.j]),
29array([[ 0.70710678+0.j, 0.70710678+0.j],
30[ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))
31Parameters:
32square matrix
33Returns
34The eigenvalues, each repeated according to its multiplicity.
35The normalized (unit "length") eigenvectors, such that the
36column ``v[:,i]`` is the eigenvector corresponding to the
37eigenvalue ``w[i]`` .

کلاس ماتریس

در ادامه مقدمه مختصری در مورد کلاس ماتریس ارائه شده است.

1>>> A = matrix('1.0 2.0; 3.0 4.0')
2>>> A
3[[ 1. 2.]
4[ 3. 4.]]
5>>> type(A) # تعیین محل ذخیره‌سازی ماتریس
6<class 'numpy.matrixlib.defmatrix.matrix'>
7>>> A.T # transpose
8[[ 1. 3.]
9[ 2. 4.]]
10>>> X = matrix('5.0 7.0')
11>>> Y = X.T
12>>> Y
13[[5.]
14[7.]]
15>>> print A*Y # ضرب ماتریس
16[[19.]
17[43.]]
18>>> print A.I # معکوس سازی
19[[-2. 1. ]
20[ 1.5 -0.5]]
21>>> solve(A, Y) #حل معادله جبری
22matrix([[-3.],
23[ 4.]])

اندیس‌گذاری: مقایسه ماتریس‌ها و آرایه‌های دوبعدی

توجه کنید که برخی تفاوت‌های مهم بین آرایه‌های NumPy و ماتریس‌ها وجود دارند. NumPy دو شی بنیادی را ارائه می‌کند: یک شی آرایه N بعدی و یک شی تابع سراسری. در NumPy اشیای دیگر بر روی این دو شی بنیادی ساخته می‌شوند. به طور خاص ماتریس‌ها اشیای آرایه‌ای دوبعدی هستند که از شی‌ء آرایه‌ای NumPy به ارث رسیده‌اند. در هر دو شی آرایه و ماتریس، اندیس‌ها باید ترکیبی صحیح از یک یا چند مورد زیر باشند:

  • اسکالرهای صحیح
  • سه‌نقطه (...)
  • فهرستی از مقادیر صحیح یا بولی
  • یک چندتایی از مقادیر صحیح یا بولی
  • یک آرایه 1 بعدی از مقادیر صحیح یا بولی

از یک ماتریس می‌توان به عنوان اندیسی برای ماتریس‌ها استفاده کرد، اما معمولاً آن را برای انجام یک کار مفروض بر روی یک آرایه، فهرست یا دیگر اشکال، نیاز خواهیم داشت. آرایه‌ها در NumPy نیز همانند پایتون از صفر شروع می‌شوند. به طور سنتی یک آرایه 2 بعدی یا ماتریس به‌صورت یک آرایه مستطیلی از ردیف‌ها و ستون‌ها نمایش می‌یابد که حرکت در راستای محور 0 در واقع حرکت در راستای ردیف‌ها و حرکت در راستای محور 1، حرکت در راستای ستون‌ها محسوب می‌شود.

در ادامه یک آرایه و یک ماتریس ایجاد می‌کنیم و آن را قطعه‌بندی می‌کنیم:

1>>> A = arange(12)
2>>> A
3array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
4>>> A.shape = (3,4)
5>>> M = mat(A.copy())
6>>> print type(A)," ",type(M)
7<type 'numpy.ndarray'> <class 'numpy.core.defmatrix.matrix'>
8>>> print A
9[[ 0 1 2 3]
10[ 4 5 6 7]
11[ 8 9 10 11]]
12>>> print M
13[[ 0 1 2 3]
14[ 4 5 6 7]
15[ 8 9 10 11]]

اینک در مورد برخی قطعه‌بندی‌های ساده صحبت می‌کنیم. قطعه‌بندی ساده به قطعه‌بندی اشیا یا اعداد صحیح گفته می‌شود. برای مثال، ارزیابی [:]A و M[:] نمونه‌های آشنایی از قطعه‌بندی اندیس‌گذاری در پایتون هستند ولی باید به این نکته مهم توجه داشته باشیم که قطعه‌بندی در NumPy یک کپی از داده‌ها ایجاد نمی‌کند. قطعه‌بندی یک نمایش جدید از همان داده‌ها ایجاد می‌کند.

1>>> print A[:]; print A[:].shape
2[[ 0 1 2 3]
3[ 4 5 6 7]
4[ 8 9 10 11]]
5(3, 4)
6>>> print M[:]; print M[:].shape
7[[ 0 1 2 3]
8[ 4 5 6 7]
9[ 8 9 10 11]]
10(3, 4)

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

1>>> print A[:,1]; print A[:,1].shape
2[1 5 9]
3(3,)
4>>> print M[:,1]; print M[:,1].shape
5[[1]
6[5]
7[9]]
8(3, 1)

به اختلاف بین دو نتیجه اخیر نگاه کنید. استفاده از یک دونقطه برای آرایه‌های دوبعدی یک آرایه‌ی 1 بعدی ایجاد می‌کند، در حالی که استفاده از آن در یک ماتریس موجب ایجاد ماتریس 2بعدی می‌شود. یک قطعه‌بندی بر روی یک ماتریس همیشه یک ماتریس ایجاد می‌کند. برای مثال، یک قطعه‌بندی بر روی [:M[2 یک ماتریس به شکل (1,4) ایجاد می‌کند. برعکس قطعه‌بندی کردن یک آرایه همواره آرایه‌ای با ابعاد در کمترین مقدار ممکن تولید می‌کند. برای مثال اگر C یک آرایه 3 بعدی باشد، [C[…,1 یک آرایه 2 بعدی ایجاد می‌کند، در حالی که [C[1,:,1 یک آرایه 1 بعدی ایجاد می‌کند. از اینجا به بعد در این نوشته، ما نتایج قطعه‌بندی آرایه را زمانی نشان خواهیم داد که نتایج با قطعه‌بندی ماتریس متناظر یکسان باشد.

فرض کنید ما ستون‌های اول و سوم یک آرایه را بخواهیم جدا کنیم. یک روش این است که با استفاده از یک فهرست آن‌ها را جدا کنیم:

1>>> A[:,[1,3]]
2array([[ 1, 3],
3[ 5, 7],
4[ 9, 11]])
5یک روش اندکی پیچیده‌تر این است که از متد take() استفاده کنیم:
6>>> A[:,].take([1,3],axis=1)
7array([[ 1, 3],
8[ 5, 7],
9[ 9, 11]])

اگر بخواهیم ردیف نخست را نداشته باشیم، باید از روش زیر استفاده کنیم:

1>>> A[1:,].take([1,3],axis=1)
2array([[ 5, 7],
3[ 9, 11]])

یا این‌که می‌توانیم به‌سادگی از [[A[1:,[1,3 استفاده کنیم. البته روش دیگری هم برای قطعه‌بندی ماتریس فوق وجود دارد که از حاصل‌ضرب خارجی استفاده می‌کند:

1>>> A[ix_((1,2),(1,3))]
2array([[ 5, 7],
3[ 9, 11]])

برای سهولت در ادامه بار دیگر آرایه را آورده‌ایم:

1>>> print A
2[[ 0 1 2 3]
3[ 4 5 6 7]
4[ 8 9 10 11]]

اینک می‌خواهیم یک کار اندکی پیچیده‌تر انجام بدهیم. فرض کنید بخواهیم همه ستون‌هایی که مقدار نخست ردیفشان بزرگ‌تر از 1 باشد را حفظ کنیم. یک روش ایجاد یک اندیس بولی است:

1>>> A[0,:]>1
2array([False, False, True, True], dtype=bool)
3>>> A[:,A[0,:]>1]
4array([[ 2, 3],
5[ 6, 7],
6[10, 11]])

این همان است که می‌خواستیم! اما اندیس‌گذاری ماتریس کار چندان آسانی نیست.

1>>> M[0,:]>1
2matrix([[False, False, True, True]], dtype=bool)
3>>> M[:,M[0,:]>1]
4matrix([[2, 3]])

مشکل این کار این است که قطعه‌بندی یک ماتریس، خود یک ماتریس ایجاد می‌کند. اما ماتریس‌ها خصوصیت A آسانی ندارند که مقدار آن بازنمایی یک آرایه باشد، بنابراین باید از روش زیر استفاده کنیم:

1>>> M[:,M.A[0,:]>1]
2matrix([[ 2, 3],
3[ 6, 7],
4[10, 11]])

اگر بخواهیم یک ماتریس را به‌صورت مشروط در دو جهت قطعه‌بندی کنیم، باید راهبرد خود را اندکی تغییر دهیم. در واقع به‌جای روش زیر:

1>>> A[A[:,0]>2,A[0,:]>1]
2array([ 6, 11])
3>>> M[M.A[:,0]>2,M.A[0,:]>1]
4matrix([[ 6, 11]])

باید از حاصل‌ضرب خارجی ix_ استفاده کنیم:

1>>> A[numpy.ix_(A[:,0]>2,A[0,:]>1)]
2array([[ 6, 7],
3[10, 11]])
4>>> M[numpy.ix_(M.A[:,0]>2,M.A[0,:]>1)]
5matrix([[ 6, 7],
6[10, 11]])

نکات و ترفندها

در این بخش برخی نکات کوتاه و مفید برای استفاده از NumPy ارائه کرده‌ایم.

تغییر شکل «خودکار»

برای تغییر دادن ابعاد یک آرایه می‌توان یکی از اندازه‌ها را نادیده گرفت و بدین ترتیب به طور خودکار کاهش می‌یابد:

1>>> a = arange(30)
2>>> a.shape = 2,-1,3 # به معنی آن چیزی که نیاز است-1
3>>> a.shape
4(2, 5, 3)
5>>> a
6array([[[ 0, 1, 2],
7[ 3, 4, 5],
8[ 6, 7, 8],
9[ 9, 10, 11],
10[12, 13, 14]],
11[[15, 16, 17],
12[18, 19, 20],
13[21, 22, 23],
14[24, 25, 26],
15[27, 28, 29]]])

پشته‌سازی بردار

چگونه می‌توان یک آرایه 2 بعدی را از یک فهرست از بردارهای با ردیف‌های هم‌اندازه ایجاد کرد؟ در متلب (MATLAB) این کار بسیار آسان است: اگر x و y دو بردار با طول یکسان باشند تنها لازم است که دستور زیر را اجرا کنید: [m=[x;y. در NumPy این کار بسته به ابعادی که پشته‌سازی در آن انجام می‌شود، از طریق تابع‌های column_stack، dstack، hstack و vstack انجام می‌شود. برای مثال:

1x = arange(0,10,2) # x=([0,2,4,6,8])
2y = arange(5) # y=([0,1,2,3,4])
3m = vstack([x,y]) # m=([[0,2,4,6,8],
4# [0,1,2,3,4]])
5xy = hstack([x,y]) # xy =([0,2,4,6,8,0,1,2,3,4])

منطق پشت این تابع‌ها برای ابعاد بالاتر از 2 ممکن است کمی عجیب به نظر برسد.

هیستوگرام‌ها

وقتی تابع histogram در NumPy بر روی یک آرایه اعمال شود، یک جفت‌بردار بازمی‌گرداند: هیستوگرام یک آرایه و بردار bin ها.

باید آگاه باشید که matplotlib هم یک تابع برای ساخت هیستوگرام‌ها دارد که از تابع موجود در NumPy متفاوت است. اختلاف اصلی این است که pylab.hist به طور خودکار هیستوگرام را ترسیم می‌کند در حالی که numpy.histogram تنها داده‌ها را ایجاد می‌کند.

1import numpy
2import pylab
3#یک بردار از 1000 متغیر نرمال با واریانس 2^0.5 و میانگین 2 ایجاد می‌کند
4mu, sigma = 2, 0.5
5v = numpy.random.normal(mu,sigma,10000)
6# یک هیستوگرام نرمال شده با 50 bin رسم می‌کند.
7pylab.hist(v, bins=50, normed=1) # matplotlib version (plot)
8pylab.show()
9# محاسبه و سپس رسم می‌کند numpy هیستوگرام را با
10(n, bins) = numpy.histogram(v, bins=50, normed=True) # NumPy version (no plot)
11pylab.plot(.5*(bins[1:]+bins[:-1]), n)
12pylab.show()

اگر تمایل به مطالعه بیشتر در مورد این موضوعات را داشته باشید؛ شاید آموزش های زیر نیز برای شما مفید باشند:

#

بر اساس رای ۸ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
github
۸ دیدگاه برای «کتابخانه NumPy پایتون – راهنمای جامع — بخش دوم»

سلام
ماژول np.argmin چیکار میکنه دقیقا؟

کاش فقط متنو ترجمه نمی کردید کاش یکمم توضیح حداقل می دادید

با سلام و خسته نباشید
خوبی سایت شما اینه که از همه مباحث سرفصل مطالب مربوط رو آورده که خیلی تو درک مطلب کمک می کنه مثلا همین برودکستینگ توی پایتون. درسته زیاد توضیحات مبسوط و درست حسابی راجع ریز مطالب ندادید و من مجبور شدم مدام سایتای خارجی رو برای بدست آوردن اطلاعات بیشتر مثلا راجع به تابع ix سرچ کنم ولی در کل تو سایتهای زبون فارسی بینظیره حتی تو سایتای خارجیم کم پیدا میشه که یه مطلبو به طور مبسوط توضیح داده باشند

سلام خيلي سايتتون مفيده گرچه زياد توضيح نداده دستوراتو ولي تنها سايت فارسيه كه مطالبو قشنگ و جامع توضيح داده بخصوص براي افراد شاغل كه كلاس حضوري نمي تونن بيان عاليه كاشكي يه دوره رفع اشكالي چيزي مي ذاشتيد كه ثبت نام مي كرديم و اشكالاتمونو برطرف مي كرديم

ضمن عرض سلام و خسته نباشید
من تازه میخام شروع به یادگیری پایتون بکنم. منتهی تمرکزم بیشتر روی یادگیری ماشین و بسته هایی مانند Numpy خاهد بود. اما از اونجایی که یادگیری خود زبان پایتون زمان بره (و اصولا بی انتها هم هست!)، به نظرتون پیش نیازهای پایتون برای داده کاوی چیست؟
ممنون

سلام دوست عزیز؛
این که یادگیری پایتون زمان‌بر یا به قول شما بی‌انتها است، نمی‌تواند دلیلی برای گام نگذاشتن در مسیر یادگیری باشد، کما این که چنین هم نیست و با کمی تلاش و پشتکار می‌توانید خیلی زود بر این زبان مسلط شوید.
اما در خصوص به دست آوردن تصویری کلی از مباحث مرتبط با داده‌کاوی، پیشنهاد می‌کنم این مطلب همکار خوبم، سرکار خانم حصارکی را مطالعه بفرمایید:
داده کاوی (Data Mining) — از صفر تا صد

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

سلام و وقت بخیر
برای محاسبه‌ میانگین حسابی ردیف‌های آرایه‌های دو بعدی(مثال با نام array) از دستور زیر استفاده می‌شود:
numpy.mean(array, axis = 1)
خروجی آن یک آرایه تک بعدی از میانگین ردیف‌های آرایه فوق است.

نظر شما چیست؟

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