حلقه روی آرایه (Array Iterating)
اینجا با مفهوم حلقه روی آرایه در نامپای آشنا می شوی. یعنی چطور روی عناصر آرایه یکی یکی راه برویم و آن ها را بخوانیم یا رویشان عملیات انجام دهیم؛ مثل این که در صف مدرسه از نفر اول تا آخر اسم ها را صدا بزنی.
حلقه روی آرایه در نامپای یعنی چه؟
در برنامه نویسی، Iterating یعنی رفتن روی عناصر، دانه دانه و پشت سر هم. در نامپای هم همین کار را با آرایه ها انجام می دهیم.
می توانیم از حلقه for پایتون برای پیمایش آرایه ها استفاده کنیم. فقط باید حواسمان به تعداد بعدها باشد.
حلقه روی آرایه های 1 بعدی
آرایه 1 بعدی مثل یک لیست ساده است؛ مثل نمره های یک درس. اگر روی این آرایه حلقه بزنیم، هر بار یک عدد ساده، یعنی یک اسکِلار (Scalar) می گیریم.
import numpy as np
arr = np.array([1, 2, 3])
for x in arr:
print(x)
اینجا حلقه for سه بار اجرا می شود. هر بار یکی از اعداد 1، 2 یا 3 را چاپ می کند.
حلقه روی آرایه های 2 بعدی
آرایه 2 بعدی مثل جدول کلاس است؛ ردیف و ستون دارد. وقتی روی آرایه 2 بعدی حلقه ساده می زنیم، هر بار یک ردیف کامل تحویل می گیریم.
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6]])
for x in arr:
print(x)
خروجی هر بار یک آرایه 1 بعدی است؛ یعنی ردیف های جدول. برای رسیدن به عددها، باید یک حلقه دیگر هم بزنیم.
رسیدن به اسکِلارها در آرایه 2 بعدی
برای رسیدن به خود عددها در آرایه 2 بعدی، روی هر ردیف هم دوباره حلقه می زنیم. یعنی حلقه تو در تو.
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6]])
for x in arr:
for y in x:
print(y)
حلقه بیرونی روی ردیف ها حرکت می کند. حلقه داخلی هم روی عددهای هر ردیف.
حلقه روی آرایه های 3 بعدی
آرایه 3 بعدی را مثل چند جدول روی هم تصور کن؛ مثل چند برگه نمره روی هم. در حلقه ساده، اول روی این برگه ها حرکت می کنیم.
import numpy as np
arr = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
for x in arr:
print(x)
اینجا هر بار یک آرایه 2 بعدی می گیریم؛ یعنی یک جدول کامل.
رسیدن به اسکِلار در آرایه 3 بعدی
برای رسیدن به عددهای تکی، باید سه حلقه تو در تو بنویسیم؛ یکی برای هر بعد.
import numpy as np
arr = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
for x in arr:
for y in x:
for z in y:
print(z)
نوشتن چند حلقه پشت هم برای بعدهای بیشتر، خسته کننده می شود. اینجاست که ابزار کمکی نامپای وارد می شود.
استفاده از nditer برای حلقه روی آرایه
nditer یک تابع کمکی نامپای است. با آن می توانیم روی تمام اسکِلارهای یک آرایه چندبعدی، با یک حلقه ساده حرکت کنیم.
یعنی دیگر لازم نیست برای هر بعد، یک for جدا بنویسی.
import numpy as np
arr = np.array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
for x in np.nditer(arr):
print(x)
در این مثال، nditer همه بعدها را برایت باز می کند. حلقه for روی خود عددهای تکی می چرخد.
حلقه روی آرایه با نوع داده متفاوت
گاهی می خواهیم هنگام پیمایش، نوع داده را عوض کنیم. مثلا اعداد را موقتا به رشته (String) تبدیل کنیم.
برای این کار، از آرگومان op_dtypes استفاده می کنیم و نوع مقصد را می دهیم. چون نامپای نوع را در جای خودش عوض نمی کند، از بافر (Buffer) موقتی استفاده می کند. برای فعال کردن بافر، باید flags=['buffered'] را بدهیم.
import numpy as np
arr = np.array([1, 2, 3])
for x in np.nditer(arr,
flags=['buffered'],
op_dtypes=['S']):
print(x)
اینجا اعداد به صورت رشته بایت چاپ می شوند. خود آرایه اصلی اما همان عددهای قبلی را نگه می دارد.
حلقه با گام های متفاوت روی آرایه
با برش (Slicing) می توانیم فقط بعضی عناصر را انتخاب کنیم. بعد روی همان زیرآرایه، با nditer حلقه بزنیم.
در مثال زیر، از هر ردیف فقط ستون های با فاصله دو تا دو تا را نگه می داریم. یعنی یک عنصر را می خوانیم، یکی را رد می کنیم.
import numpy as np
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
for x in np.nditer(arr[:, ::2]):
print(x)
عبارت arr[:, ::2] یعنی تمام ردیف ها، اما ستون ها را با گام 2 بردار. این روش برای حلقه روی آرایه در نامپای با فیلتر ساده، خیلی کاربردی است.
حلقه شماره دار با ndenumerate
گاهی علاوه بر مقدار، به اندیس عنصر هم نیاز داریم. اندیس (Index) یعنی آدرس عنصر در آرایه.
تابع ndenumerate هنگام پیمایش، هم اندیس و هم مقدار را به ما می دهد.
حلقه شماره دار روی آرایه 1 بعدی
import numpy as np
arr = np.array([1, 2, 3])
for idx, x in np.ndenumerate(arr):
print(idx, x)
اینجا idx خودش یک تاپل است؛ مثلا (0,)، (1,). عدد داخل تاپل، موقعیت عنصر است.
حلقه شماره دار روی آرایه 2 بعدی
import numpy as np
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
for idx, x in np.ndenumerate(arr):
print(idx, x)
حالا اندیس ها دو تایی هستند؛ مثل (0, 2). عدد اول شماره ردیف است، عدد دوم شماره ستون.
چند تمرین برای حلقه روی آرایه در نامپای
برای تمرین بهتر، این کارها را انجام بده:
- یک آرایه 2 بعدی بساز و با حلقه ساده، فقط ردیف ها را چاپ کن.
- با حلقه تو در تو، همان آرایه را تا اسکِلارها پیمایش کن.
- یک آرایه 3 بعدی بساز و با
np.nditerروی همه عددها حلقه بزن.
اگر شکل آرایه ها را فراموش کردی، صفحه شکل آرایه در نامپای کمک خوبی است. برای روش های تغییر شکل هم به صفحه تغییر شکل آرایه در نامپای سر بزن.
در نهایت، این صفحه یعنی حلقه روی آرایه در نامپای مرجع اصلی تو برای مرور این مبحث است.
جمع بندی سریع
- حلقه روی آرایه در نامپای یعنی پیمایش دانه دانه عناصر آرایه.
- در آرایه های چندبعدی، حلقه ساده روی بعدهای بالاتر حرکت می کند.
np.nditerکمک می کند با یک حلقه ساده، همه اسکِلارها را ببینی.- با
op_dtypesو بافر می توانی نوع داده را هنگام پیمایش عوض کنی. np.ndenumerateهم مقدار را می دهد هم اندیس عنصر را.