ترانهاده
علاوه بر بازآرایی (که اندازه ابعاد آرایه را تغییر میداد) ما میتوانیم ترتیب ابعاد را نیز عوض کنیم. برای این منظور باید از دستور T یا transpose (بدون هیچ ورودی) استفاده کنیم. برای نمونه اگر یک آرایه دو بُعدی 2 در 3 (2 سطر و 3 ستون) داشته باشیم، اگر از این دستور استفاده کنیم جای سطر و ستون عوض میشود. یعنی آرایه ما 3 در 2 (3 سطر و 2 ستون) میشود. به مثال زیر توجه کنیم:
a = np.arange(8).reshape(2, 4)
print(a)
print(a.T)
خروجی کد:
[[0 1 2 3]
[4 5 6 7]]
[[0 4]
[1 5]
[2 6]
[3 7]]
همانطور که میبینیم، آرایه 2 در 4 ما به راحتی توسط دستور T به آرایه 4 در 2 تبدیل شد.
نکته: توجه کنیم که خود آرایه a تغییری نمیکند. یعنی در مثال بالا اگر دوباره آرایه a را چاپ کنیم همان 2 در4 قبلی است.
حال یک مثال با استفاده از دستور transpose را ببینیم. در این مثال از یک آرایه تصادفی 3 در 2 در 4 استافده کردهایم و سپس با استفاده از دستور transpose ترتیب ابعاد را تغییر دادهایم.
b = np.random.randint(1, 6, (3, 2, 4))
print(b)
print(b.shape)
c = b.transpose()
print("--------------------")
print(c)
print(c.shape)
خروجی کد:
[[[4 2 2 4]
[2 5 4 4]]
[[5 1 1 4]
[5 5 1 2]]
[[3 3 4 4]
[2 1 2 4]]]
(3, 2, 4)
--------------------
[[[4 5 3]
[2 5 2]]
[[2 1 3]
[5 5 1]]
[[2 1 4]
[4 1 2]]
[[4 4 4]
[4 2 4]]]
(4, 2, 3)
در کد بالا میبینیم که آرایه b دارای ابعاد 3 در 2 در 4 است. سپس ترانهاده آن را در c قرار دادیم که نتیجه آن تغییر ابعاد به 4 در 2 در 3 است.
دستور transpose ترتیب ابعاد آرایه را برعکس میکند. اما ما میتوانیم ترتیب دلخواه خود را نیز اعمال کنیم. برای این منظور کافیست تا جایگاه (اندیس) بعد مورد نظر را در دستور transpose وارد کنیم. برای این که بهتر متوجه شویم مثال زیر را ببینید:
در مثال زیر یک آرایه 3 بُعدی با اندازه ابعاد 2 در 5 در 3 تعریف کردهایم و میخواهیم ترتیب ابعاد را به 5 در 3 در 2 تغییر دهیم برای این منظور کافیست تا از دستور transpose با ورودی 1، 2 و 0 استفاده کنیم. چرا که در جایگاه 1 5 قرار دارد و ما میخواهیم که در ترتیب جدید به بعد 0 بیاید پس در اولین ورودی عدد 1 را میدهیم (به این معنا که در جایگاه 0 آرایه جدید شماره بعد 1 از آرایه قبلی بنشیند) و به همین ترتیب شمارههای دیگر را نیز قرار میدهیم.
a = np.random.random((2, 5, 3))
print(a)
print("a shape ->", a.shape)
b = a.transpose(1, 2, 0)
print(b)
print("b shape ->", b.shape)
خروجی کد:
[[[0.18749327 0.87129197 0.28811995]
[0.21486683 0.06825983 0.09774465]
[0.66705669 0.65409473 0.52852304]
[0.6247792 0.81215997 0.70393984]
[0.82500087 0.98916192 0.45640454]]
[[0.97015563 0.96312065 0.88499204]
[0.06734807 0.44462688 0.36215217]
[0.77130131 0.35455501 0.66906315]
[0.81050375 0.87905645 0.63527936]
[0.70265738 0.63902388 0.41252257]]]
a shape -> (2, 5, 3)
[[[0.18749327 0.97015563]
[0.87129197 0.96312065]
[0.28811995 0.88499204]]
[[0.21486683 0.06734807]
[0.06825983 0.44462688]
[0.09774465 0.36215217]]
[[0.66705669 0.77130131]
[0.65409473 0.35455501]
[0.52852304 0.66906315]]
[[0.6247792 0.81050375]
[0.81215997 0.87905645]
[0.70393984 0.63527936]]
[[0.82500087 0.70265738]
[0.98916192 0.63902388]
[0.45640454 0.41252257]]]
b shape -> (5, 3, 2)
پس به طور خلاصه در مثال بالا بُعد دوم آریه اصلی (شماره 1) تبدیل به بُعد اول (شماره 0) آرایه جدید شد.
بُعد سوم آریه اصلی (شماره 2) تبدیل به بُعد دوم (شماره 1) آرایه جدید شد.
بُعد اول آریه اصلی (شماره 0) تبدیل به بُعد سوم (شماره 0) آرایه جدید شد.
الحاق
ما میتوانیم چند آرایه را به هم متصل کنیم. برای این منظور از دستور concatenate استفاده میکنیم. فقط باید توجه کنیم که در چه راستایی (جهت محور) میخواهیم آرایهها به هم متصل شوند. برای این که با جهت محور آرایهها بیشتر آشنا شویم تصویر زیر را مشاهده کنید.
منبع:https://bigfundu.medium.com/numpy-basics-4-fbd93ab72164
برای مثال در یک آرایه دو بٌعدی محور 0 (axis=0) همان محور مربوط به سطرها است (جهت بالا به پایین) و محور 1 (axis=1) همان محور مربوط به ستونها است (جهت چپ به راست)
پس بنابراین برای استفاده از دستور concatenate باید ذکر کنیم که در چه راستایی میخواهیم آرایههای ما به هم بچسبند. باید توجه کنیم که آرایهها باید در جهت سایر محورها ابعاد یکسانی داشته باشند. حال مثالها زیر را مشاهده کنید:
a1 = np.arange(6).reshape(2, 3)
print("a1:")
print(a1)
print("a1 shape ->", a1.shape)
print('-------------------------------')
a2 = np.arange(9).reshape(3, 3)
print("a2:")
print(a2)
print("a2 shape ->", a2.shape)
print('-------------------------------')
a3 = np.array([[100, 200, 300]])
print("a3:")
print(a3)
print("a3 shape ->", a3.shape)
print('-------------------------------')
result = np.concatenate([a1, a2, a3], axis=0)
print("result:")
print(result)
print("result shape ->", result.shape)
خروجی کد:
a1:
[[0 1 2]
[3 4 5]]
a1 shape -> (2, 3)
-------------------------------
a2:
[[0 1 2]
[3 4 5]
[6 7 8]]
a2 shape -> (3, 3)
-------------------------------
a3:
[[100 200 300]]
a3 shape -> (1, 3)
-------------------------------
result:
[[ 0 1 2]
[ 3 4 5]
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[100 200 300]]
result shape -> (6, 3)
در کد بالا 3 آرایه a1 و a2 و a3 را در جهت بالا به پایین به هم متصل کردیم.
حال مثالی را ببینیم که 2 آرایه را در جهت چپ به راست (یعنی محور 1) به هم متصل کنیم.
a1 = np.random.randint(1, 10, (3, 4))
print("a1:")
print(a1)
print("a1 shape ->", a1.shape)
print('-------------------------------')
a2 = np.random.randint(20, 30, (3, 7))
print("a2:")
print(a2)
print("a2 shape ->", a2.shape)
print('-------------------------------')
result = np.concatenate([a1, a2], axis=1)
print("result:")
print(result)
print("result shape ->", result.shape)
خروجی کد:
a1:
[[2 8 8 1]
[9 7 2 4]
[9 3 6 9]]
a1 shape -> (3, 4)
-------------------------------
a2:
[[20 25 28 29 26 27 25]
[21 21 21 20 20 22 27]
[24 23 22 26 24 20 25]]
a2 shape -> (3, 7)
-------------------------------
result:
[[ 2 8 8 1 20 25 28 29 26 27 25]
[ 9 7 2 4 21 21 21 20 20 22 27]
[ 9 3 6 9 24 23 22 26 24 20 25]]
result shape -> (3, 11)
نکته: در مثالهای بالا و مثالهای قبلتر دیده شد که از متدهای مثل arange() و یا random() و یا randint() استفاده کردیم. اینکار ما صرفاً برای این است که خودمان آرایهها را دستی ایجاد نکنیم و از امکانات نامای برای ساخت آرایه کمک بگیریم.
شکافتن
عمل شکافتن دقیقاً برعکس عمل الحاق است. در واقع در این بخش یادمیگیریم که چگونه یک آرایه را به چند بخش مساوی بشکنیم یا تقسیم کنیم. برای این منظور از دستور split استفاده میکنیم. استفاده از دستور split به دو روش امکان پذیر است.
روش اول:
در این روش میخواهیم آرایه را به چند قسمت مساوی تقسیم کنیم. بنابراین این تعداد و راستایی (جهت محور) که میخواهیم را باید به دستور split بگوییم و باید توجه کنیم که حتماً حتماً اندازه بُعد آرایه در جهت محور مورد نظر ما به این تعداد بخش پذیر باشد. مثال زیر را توجه کنیم:
a = np.random.randint(1, 10, (3, 10))
print("a:")
print(a)
print("a shape ->", a.shape)
print('-------------------------------')
p1, p2 = np.split(a, 2, axis=1)
print("p1:")
print(p1)
print("p1 shape ->", p1.shape)
print('-------------------------------')
print("p2:")
print(p2)
print("p2 shape ->", p2.shape)
print('-------------------------------')
خروجی کد:
a:
[[7 1 4 7 8 5 5 3 5 5]
[7 1 3 5 6 2 8 5 6 1]
[1 8 8 1 4 7 9 7 4 1]]
a shape -> (3, 10)
-------------------------------
p1:
[[7 1 4 7 8]
[7 1 3 5 6]
[1 8 8 1 4]]
p1 shape -> (3, 5)
-------------------------------
p2:
[[5 5 3 5 5]
[2 8 5 6 1]
[7 9 7 4 1]]
p2 shape -> (3, 5)
-------------------------------
روش دوم:
در این روش تقسیم آرایه بر اساس نقاط شکست مشخص میشود. منظور از نقاط شکست جایگاههایی است که در آن راستا میخواهیم آرایه ما تقسیم شود. به مثال زیر توجه کنیم:
a = np.random.randint(1, 10, (3, 10))
print("a:")
print(a)
print("a shape ->", a.shape)
print('-------------------------------')
p1, p2, p3 = np.split(a, [3, 5], axis=1)
print("p1:")
print(p1)
print("p1 shape ->", p1.shape)
print('-------------------------------')
print("p2:")
print(p2)
print("p2 shape ->", p2.shape)
print('-------------------------------')
print("p3:")
print(p3)
print("p3 shape ->", p3.shape)
print('-------------------------------')
خروجی کد:
a:
[[7 7 6 9 6 4 3 4 4 9]
[8 6 7 8 8 5 9 4 7 6]
[4 9 2 1 7 5 2 7 8 9]]
a shape -> (3, 10)
-------------------------------
p1:
[[7 7 6]
[8 6 7]
[4 9 2]]
p1 shape -> (3, 3)
-------------------------------
p2:
[[9 6]
[8 8]
[1 7]]
p2 shape -> (3, 2)
-------------------------------
p3:
[[4 3 4 4 9]
[5 9 4 7 6]
[5 2 7 8 9]]
p3 shape -> (3, 5)
-------------------------------
در کد بالا در راستای محور 1 (چپ به راست یا محور مربوط به ستونها) در اندیس (شماره ستون) 3 و 5 آرایه را شکافتیم که در نتیجه آن 3 آرایه حاصل میشود.