Home »
Blog »
AI/ML Engineer সিরিজ » Series 03 » Episode 02
NumPy: array, shape, vectorization — ML-এর নিচে যে গণিত চলে
loop ভুলে যান, array-তে চিন্তা করুন (Series 03, Episode 02)
🟢 BEGINNER
Series 03 — Data — AI-এর ভিত্তি
Episode 02 / 09
📑 এই পর্বে যা যা আছে
- ১. গল্প: Rahim-এর "ধীরগতি" code
- ২. সমস্যা: Python list দিয়ে বড় data-তে কেন আটকায়
- ৩. NumPy কী এবং কেন এটা ML-এর ভিত্তি
- ৪. তিন Level-এ array বোঝা
- ৫. Array, dimension আর shape — মূল ধারণা
- ৬. Indexing ও slicing
- ৭. Vectorization: loop ছাড়াই হিসাব
- ৮. Broadcasting: ভিন্ন shape-এর array একসাথে
- ৯. Experiment: loop বনাম vectorization-এর গতি
- ১০. বাস্তব উদাহরণ: salary data নিয়ে হিসাব
- ১১. একজন AI Engineer-এর দৃষ্টিতে NumPy
- ১২. Boss Question
- ১৩. Job Requirement Decoder
- ১৪. সাধারণ ভুল ধারণা
- ১৫. Interview Prep
- ১৬. হাতে-কলমে (Mini Exercise)
- ১৭. Project Connection
- ১৮. সারসংক্ষেপ
- ১৯. পরবর্তী পর্বে কী শিখব
🧩 ১. গল্প: Rahim-এর "ধীরগতি" code
Rahim ঠিক করল ১০ লাখ job post-এর salary-তে ৫% বৃদ্ধি হলে নতুন salary কত হবে সেটা হিসাব করবে। সে
যেভাবে সবসময় করে, সেভাবেই একটা Python for loop লিখল। code চলল, কিন্তু... অনেকক্ষণ।
Rahim: "Nila আপা, আমার loop তো ঠিকই কাজ করছে, কিন্তু এত slow কেন? আর data
Analyst-রা দেখি সবাই numpy import করে। এটা না করলে হয় না?"
Nila: "হয়, কিন্তু তুমি data-র জগতে সবচেয়ে গুরুত্বপূর্ণ চিন্তার ধরনটা মিস করছ।
বড় data-তে আমরা 'একটা একটা করে' চিন্তা করি না — আমরা 'পুরো array একসাথে' চিন্তা করি। এই একটা mindset
বদল তোমার code-কে ১০০ গুণ দ্রুত করে দেবে। এর নাম vectorization।"
আজ আমরা শিখব NumPy — যেটা Pandas, scikit-learn, PyTorch — সব ML tool-এর নিচে চুপচাপ কাজ করে। NumPy
না বুঝলে ওপরের সব tool শুধু "magic" মনে হবে; বুঝলে সব পরিষ্কার হয়ে যাবে।
❓ ২. সমস্যা: Python list দিয়ে বড় data-তে কেন আটকায়
Python-এর সাধারণ list দুর্দান্ত, কিন্তু সংখ্যার বড় হিসাবের জন্য দুটো বড় সমস্যা আছে:
- ধীর: list-এর প্রতিটা element আলাদা Python object; loop-এ প্রতিবার Python interpreter কাজ করে — তাই লাখ লাখ সংখ্যায় ধীর।
- অসুবিধাজনক: দুটো list যোগ করতে গেলে (
[1,2] + [3,4]) সেটা যোগ না করে জোড়া লাগিয়ে দেয় ([1,2,3,4]) — গাণিতিক যোগ করতে loop লাগে।
NumPy এই দুটো সমস্যাই সমাধান করে, কারণ এটা সংখ্যাগুলো একটানা memory-তে (contiguous) রাখে এবং হিসাব C-এর গতিতে করে।
📚 ৩. NumPy কী এবং কেন এটা ML-এর ভিত্তি
NumPy (Numerical Python) হলো সংখ্যাভিত্তিক হিসাবের core library। এর মূল জিনিস হলো
ndarray — একটা n-dimensional array। প্রায় সব ML data শেষ পর্যন্ত সংখ্যার array-তে
পরিণত হয়: একটা ছবি = pixel-এর array, একটা table = সংখ্যার 2D array, একটা model-এর weight = array।
কেন এই tech? Pandas, scikit-learn, PyTorch, TensorFlow — সবাই ভেতরে NumPy (বা তার
মতো array) ব্যবহার করে। তাই NumPy শেখা মানে পুরো ML stack-এর ভিত্তি শেখা। এটা optional নয়, foundational।
🪜 ৪. তিন Level-এ array বোঝা
Level 1 — সহজ intuition
একটা array হলো একটা বাক্সের সারি, যেখানে প্রতিটা বাক্সে একটা করে সংখ্যা। একটা list-ও তো
তাই — কিন্তু পার্থক্য হলো, NumPy array-তে সব বাক্স একই ধরনের (সব সংখ্যা) আর পাশাপাশি সাজানো, যাতে
computer একসাথে দ্রুত সব বাক্স নিয়ে কাজ করতে পারে।
Level 2 — technical ভাবে
NumPy array একটা fixed data type (dtype, যেমন int64, float64)
মেনে চলে এবং একটানা memory block-এ থাকে। এই কারণে NumPy পুরো array-র উপর একটাই optimized C-loop চালাতে
পারে — Python-এর ধীর loop এড়িয়ে। এটাকেই বলে vectorized operation।
Level 3 — engineer দৃষ্টিতে
একজন AI Engineer array-তে চিন্তা করে "shape" দিয়ে। একটা image batch হয়তো shape
(32, 3, 224, 224) — মানে ৩২টা ছবি, ৩ channel (RGB), 224x224 pixel। shape না বুঝলে
Deep Learning-এ প্রতি পদে "shape mismatch" error খেতে হবে। তাই engineer সবসময় জিজ্ঞেস করে: "এই array-র shape কী?"
📐 ৫. Array, dimension আর shape — মূল ধারণা
import numpy as np
# 1D array (vector) — একটা সংখ্যার সারি
a = np.array([10, 20, 30, 40])
print(a.ndim) # 1 -> dimension সংখ্যা
print(a.shape) # (4,) -> ৪টা element
print(a.dtype) # int64
# 2D array (matrix) — row ও column
b = np.array([[1, 2, 3],
[4, 5, 6]])
print(b.ndim) # 2
print(b.shape) # (2, 3) -> ২ row, ৩ column
print(b.size) # 6 -> মোট element
# সুবিধাজনক array তৈরি
zeros = np.zeros((2, 3)) # সব 0
ones = np.ones((3,)) # সব 1
rng = np.arange(0, 10, 2) # [0 2 4 6 8]
lin = np.linspace(0, 1, 5) # 0 থেকে 1 এর মধ্যে সমান ব্যবধানে ৫টা
এই ছবিটা shape ও dimension-এর ধারণা পরিষ্কার করবে:
0D (scalar) 1D (vector) 2D (matrix) 3D (tensor)
7 [7 8 9] [[1 2 3] অনেকগুলো matrix
[4 5 6]] একসাথে (যেমন ছবির batch)
shape () shape (3,) shape (2, 3) shape (n, r, c)
🎯 ৬. Indexing ও slicing
import numpy as np
a = np.array([10, 20, 30, 40, 50])
print(a[0]) # 10 -> প্রথম element
print(a[-1]) # 50 -> শেষ element
print(a[1:4]) # [20 30 40] -> index 1 থেকে 3
b = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(b[0, 2]) # 3 -> row 0, column 2
print(b[:, 1]) # [2 5 8] -> সব row-এর column 1
print(b[1, :]) # [4 5 6] -> row 1 এর সব column
# Boolean indexing — খুব শক্তিশালী (filtering-এর ভিত্তি)
salaries = np.array([25000, 60000, 40000, 90000])
high = salaries[salaries > 50000]
print(high) # [60000 90000]
মনে রাখুন: ওপরের salaries[salaries > 50000] লাইনটাই হলো Pandas-এর
filtering-এর মূল ভিত্তি। Pandas আসলে এই NumPy boolean indexing-কেই সুন্দরভাবে wrap করে। তাই এটা বুঝলে
পরের episode-এ Pandas filtering সহজ লাগবে।
⚡ ৭. Vectorization: loop ছাড়াই হিসাব
Rahim-এর সমস্যায় ফিরি — সব salary-তে ৫% বৃদ্ধি। loop দিয়ে বনাম NumPy দিয়ে:
import numpy as np
salaries = np.array([25000, 40000, 60000, 90000])
# ❌ পুরোনো ধরন (loop) — ধীর, বেশি code
new_list = []
for s in salaries:
new_list.append(s * 1.05)
# ✅ vectorized ধরন — একটা লাইন, অনেক দ্রুত
new_salaries = salaries * 1.05
print(new_salaries) # [26250. 42000. 63000. 94500.]
# আরও উদাহরণ — পুরো array-তে একসাথে হিসাব
print(salaries.mean()) # গড়
print(salaries.max()) # সর্বোচ্চ
print(salaries.sum()) # মোট
print((salaries > 50000).sum()) # কতজনের salary 50k-এর বেশি
খেয়াল করুন — salaries * 1.05 লেখায় কোনো loop নেই, তবু প্রতিটা element-এ হিসাব হয়েছে।
এটাই vectorization: "একটা একটা" নয়, "পুরো array একসাথে"।
📡 ৮. Broadcasting: ভিন্ন shape-এর array একসাথে
Broadcasting হলো NumPy-র একটা চতুর নিয়ম — এটা ছোট array-কে "প্রসারিত" (stretch) করে বড় array-র সাথে
মেলায়, আসলে data কপি না করেই। উদাহরণ দিয়ে দেখি:
import numpy as np
# scalar broadcasting — 1.05 প্রতিটা element-এ ছড়িয়ে গেল
salaries = np.array([25000, 40000, 60000])
print(salaries * 1.05)
# 2D + 1D broadcasting
# প্রতিটা কর্মীর ৩ মাসের salary (row = কর্মী, column = মাস)
monthly = np.array([[25000, 25000, 27000],
[40000, 42000, 42000]])
bonus = np.array([1000, 1000, 2000]) # প্রতি মাসের bonus (shape 3,)
total = monthly + bonus # bonus প্রতিটা row-তে যোগ হলো
print(total)
# [[26000 26000 29000]
# [41000 43000 44000]]
Broadcasting যেভাবে কাজ করে (2D + 1D):
monthly (2,3) bonus (3,) -> প্রতিটা row-তে ছড়িয়ে যায়
[[25000 25000 27000] [1000 1000 2000]
[40000 42000 42000]] [1000 1000 2000] (মনে মনে কপি)
---------------------
ফল: প্রতিটা মাসের bonus সব কর্মীর সাথে যোগ
নিয়ম (সরলভাবে): দুটো array-র shape ডান দিক থেকে মেলানো হয়। প্রতিটা dimension হয় সমান
হতে হবে, নয়তো একটা 1 হতে হবে (তখন সেটা প্রসারিত হয়)। shape (2,3) আর (3,)
মেলে, কিন্তু (2,3) আর (2,) মেলে না — shape mismatch error দেবে।
🔬 ৯. Experiment: loop বনাম vectorization-এর গতি
নিজে চালিয়ে দেখুন — এই পার্থক্যটা চোখে দেখলে vectorization-এর গুরুত্ব গেঁথে যাবে:
import numpy as np
import time
n = 1_000_000
data = np.arange(n)
# পদ্ধতি ১ — Python loop
start = time.time()
result = [x * 2 for x in data]
print("Loop:", round(time.time() - start, 4), "সেকেন্ড")
# পদ্ধতি ২ — NumPy vectorization
start = time.time()
result = data * 2
print("NumPy:", round(time.time() - start, 4), "সেকেন্ড")
# সাধারণত NumPy ১০x থেকে ১০০x পর্যন্ত দ্রুত হয়
কী লক্ষ করবেন: NumPy version নাটকীয়ভাবে দ্রুত। ১০ লাখ সংখ্যায় পার্থক্য চোখে পড়ে,
আর real ML data-তে (লাখ-কোটি row) এই পার্থক্যই "চলে না" আর "চলে"-র মধ্যে ব্যবধান তৈরি করে।
🇧🇩 ১০. বাস্তব উদাহরণ: salary data নিয়ে হিসাব
ধরুন আমাদের job market data থেকে কিছু salary নিয়ে দ্রুত কিছু প্রশ্নের উত্তর বের করব:
import numpy as np
# বাংলাদেশের কিছু tech job-এর মাসিক salary (টাকায়)
salaries = np.array([25000, 35000, 45000, 60000,
80000, 120000, 30000, 55000])
print("গড় salary:", salaries.mean()) # 56250.0
print("মধ্যম (median):", np.median(salaries)) # 50000.0
print("সর্বোচ্চ:", salaries.max()) # 120000
print("সবচেয়ে কম:", salaries.min()) # 25000
# কতজনের salary গড়ের চেয়ে বেশি?
above_avg = (salaries > salaries.mean()).sum()
print("গড়ের বেশি:", above_avg, "জন") # 3 জন
# সবাইকে 8% increment দিলে
print("increment পরে:", salaries * 1.08)
লক্ষ করুন — mean() আর median() আলাদা (56250 বনাম 50000)। কারণ একটা বড় salary
(120000) গড়কে টেনে ওপরে তুলছে। এই "গড় বনাম মধ্যম" পার্থক্য outlier বোঝার জন্য গুরুত্বপূর্ণ — Series 04
(statistics)-এ আরও বিস্তারিত আসবে।
🔍 ১১. একজন AI Engineer-এর দৃষ্টিতে NumPy
engineer রা NumPy নিয়ে যেভাবে ভাবে:
- Shape-first চিন্তা: নতুন array পেলে প্রথমে
.shape দেখে — বেশিরভাগ bug এখানেই ধরা পড়ে।
- Loop এড়ানো: কোথাও data-র উপর Python loop দেখলে ভাবে "এটা কি vectorize করা যায়?"
- Memory সচেতনতা:
float64 বনাম float32 — বড় data-তে dtype মেমরি ও গতিতে পার্থক্য আনে।
- Reproducibility: random কাজে
np.random.seed() বা default_rng(seed) ব্যবহার করে, যাতে ফল বারবার একই আসে।
💼 ১২. Boss Question
Boss: "আমরা তো data analyst, আমাদের কাজ report বানানো। এই array-shape-vectorization
নিয়ে মাথা ঘামানোর দরকার কী? Excel দিয়েই তো হয়!"
উত্তর: Excel কয়েক হাজার row পর্যন্ত ঠিক আছে। কিন্তু আমাদের job market data যখন লাখ লাখ
row হবে, Excel hang করবে, আর প্রতিটা report হাতে বানাতে ঘণ্টা লাগবে। NumPy (এবং তার উপর Pandas) দিয়ে
সেই একই হিসাব সেকেন্ডে হয়, বারবার automate করা যায়, ভুলও কম হয়। মানে দ্রুত সিদ্ধান্ত, কম মানুষ-ঘণ্টা,
আর scalability — এটাই business value।
🔎 ১৩. Job Requirement Decoder
"Proficiency in Python and NumPy for numerical computing and array operations."
| প্রশ্ন | উত্তর |
| এর মানে কী? | আপনি NumPy array দিয়ে সংখ্যার হিসাব করতে পারেন — loop ছাড়াই, vectorized উপায়ে। |
| কোম্পানি কেন চায়? | বড় data-তে দ্রুত, নির্ভরযোগ্য হিসাব দরকার; Pandas ও ML tool-ও ভেতরে NumPy চালায়। |
| কোন সমস্যা সমাধান করে? | ধীর, ভুলপ্রবণ manual/loop-ভিত্তিক হিসাবের সমস্যা। |
| Junior-এর কী জানা লাগে? | array তৈরি, shape/dimension, indexing/slicing, boolean indexing, vectorized হিসাব, broadcasting-এর মূল ধারণা। |
| এখনই কী master লাগে না? | উন্নত linear algebra internals, GPU array (CuPy), memory-view কারিগরি — পরে। |
| GitHub-এ কীভাবে দেখাবেন? | একটা notebook যেখানে loop বনাম vectorization-এর গতি তুলনা, আর real data-তে NumPy দিয়ে হিসাব। |
| Interview-তে কী জিজ্ঞেস করতে পারে? | "vectorization কেন দ্রুত?", "broadcasting কী?", "list বনাম NumPy array-র পার্থক্য?" |
⚠️ ১৪. সাধারণ ভুল ধারণা
ভুল ১: "NumPy array আর Python list একই জিনিস।" →
ঠিক: array-র fixed dtype ও contiguous memory থাকে; এটাই গতি ও vectorization সম্ভব করে।
ভুল ২: "list1 + list2 যোগফল দেয়।" →
ঠিক: Python list-এ এটা concatenate করে; NumPy array-তে এটা element-wise যোগ করে।
ভুল ৩: "সব সময় loop লিখতে হবে।" →
ঠিক: data-র হিসাবে loop প্রায়ই vectorize করা যায় — দ্রুত ও পরিষ্কার।
ভুল ৪: "broadcasting যেকোনো shape মেলায়।" →
ঠিক: নির্দিষ্ট নিয়ম আছে; নাহলে shape mismatch error — shape সবসময় খেয়াল রাখুন।
ভুল ৫: "shape (4,) আর (4,1) একই।" →
ঠিক: একটা 1D vector, অন্যটা 2D column — broadcasting-এ ভিন্ন আচরণ করে।
🎤 ১৫. Interview Prep
প্রশ্ন ১: Vectorization কেন Python loop-এর চেয়ে দ্রুত?
উত্তর: NumPy পুরো array-তে একটাই optimized C-loop চালায়, প্রতি element-এ ধীর Python interpreter overhead এড়ায়; data contiguous memory-তে থাকে।
প্রশ্ন ২: Broadcasting কী?
উত্তর: ভিন্ন shape-এর array-কে নিয়মমাফিক "প্রসারিত" করে element-wise operation চালানো, আসল data কপি না করেই।
প্রশ্ন ৩: a.shape আর a.ndim-এর পার্থক্য?
উত্তর: shape প্রতিটা dimension-এ কতগুলো element তা বলে (যেমন (2,3)); ndim মোট dimension সংখ্যা (যেমন 2)।
প্রশ্ন ৪: boolean indexing কী কাজে লাগে?
উত্তর: শর্ত অনুযায়ী element বেছে নিতে (যেমন a[a > 50000]) — এটাই Pandas filtering-এর ভিত্তি।
✍️ ১৬. হাতে-কলমে (Mini Exercise)
🧪 হাতে-কলমে: একটা Python file-এ নিচের কাজগুলো করুন (কোনো for loop ছাড়া):
১. experience = np.array([1, 3, 5, 2, 8, 0, 4]) তৈরি করুন (বছরে অভিজ্ঞতা)।
২. গড় ও median অভিজ্ঞতা বের করুন।
৩. কতজনের অভিজ্ঞতা ৩ বছরের বেশি — boolean indexing দিয়ে গুনুন।
৪. সবার অভিজ্ঞতায় ১ যোগ করুন (এক বছর পরে) — vectorized ভাবে।
৫. একটা 2D array [[1,2],[3,4]]-এ প্রতিটা row-তে [10, 20] যোগ করুন (broadcasting)।
প্রতিটার shape print করে যাচাই করুন আপনি যা ভাবছেন সেটাই আসছে কিনা।
🚀 ১৭. Project Connection
আমাদের flagship "Bangladesh Tech Career Assistant" (V2 — Data Analyzer)-এ NumPy কাজে
লাগবে যখন আমরা salary-র উপর দ্রুত হিসাব করব — গড়, median, percentile, increment simulation। যদিও আমরা
বেশিরভাগ কাজ Pandas দিয়ে করব, Pandas ভেতরে NumPy-ই চালায়, তাই এই ভিত্তিটা এখন গেঁথে নেওয়া জরুরি।
বিশেষভাবে boolean indexing (salaries > X) আর vectorized হিসাব — এই দুটো ধারণা পরের episode-এ
Pandas filtering আর column হিসাবে সরাসরি ব্যবহার হবে।
📌 ১৮. সারসংক্ষেপ
এই Episode-এ আমরা শিখলাম:
✓ NumPy array — fixed dtype, contiguous memory — তাই দ্রুত ও ML-এর ভিত্তি
✓ shape, dimension, ndim — array বোঝার মূল ভাষা; engineer রা shape-first চিন্তা করে
✓ indexing/slicing ও boolean indexing — data বেছে নেওয়ার হাতিয়ার (Pandas filtering-এর ভিত্তি)
✓ vectorization — loop ছাড়াই পুরো array-তে হিসাব, ১০x-১০০x দ্রুত
✓ broadcasting — ভিন্ন shape-এর array নিয়মমাফিক একসাথে হিসাব
✓ mean বনাম median-এ পার্থক্য outlier-এর ইঙ্গিত দেয়
➡️ ১৯. পরবর্তী পর্বে কী শিখব
পরবর্তী Episode (S03E03): "Pandas Part 1: DataFrame, filtering, selection — data-র
Excel-on-steroids।"
NumPy দিয়ে সংখ্যার array তো বুঝলাম, কিন্তু real data-তে column-এর নাম থাকে ("salary", "city"), আর মিশ্র
ধরনের value থাকে। এখানেই আসে Pandas — NumPy-র উপর তৈরি, কিন্তু label ও mixed data সামলাতে পারে।
পরের পর্বে আমরা প্রথমবার একটা real job dataset load করে slice করা শুরু করব।