পাঠ ০৯ · ২৫-এর মধ্যে · মডিউল ২
Home / AI Courses / AI-এর জন্য Python / NumPy পরিচিতি

NumPy পরিচিতি — ndarray কী

NumPy intro — the ndarray
৭ মিনিট পড়া শুরু · Beginner ব্রাউজারে কোড চালান

এই পাঠে যা শিখবেন

  • NumPy কী এবং AI-তে কেন এত গুরুত্বপূর্ণ
  • ndarray বনাম Python list — speed ও memory পার্থক্যের কারণ
  • Array তৈরি — np.array, zeros, arange, linspace, random
  • Array attributes — shape, dtype, ndim, size, itemsize, nbytes
  • Reshape, ravel, transpose — shape পরিবর্তন
  • Vectorization — loop ছেড়ে array operation
  • Aggregation — sum/mean/std সহ axis parameter
  • AI-এ ndarray কোথায় ব্যবহার — image, batch, embedding, weight

১ · NumPy কী এবং কেন

NumPyNumPy"Numerical Python" — Travis Oliphant ২০০৬-এ প্রকাশ করেন। Python-এ সংখ্যাগত গণনার ভিত্তি লাইব্রেরি। C ও Fortran-এ implemented; PyTorch, TensorFlow, scikit-learn, Pandas — সবই NumPy-র উপর গড়া। হলো Python-এ সংখ্যাগত গণনার ভিত্তি লাইব্রেরি। এর কেন্দ্রে আছে ndarrayndarray"N-dimensional array" — একই dtype-এর সংখ্যার contiguous memory block। NumPy-র কেন্দ্রীয় data structure। ছবি, audio, embedding, weight — সব এতে রাখা হয়। — N-মাত্রিক একক একটি data structure যেখানে একই type-এর সংখ্যা পাশাপাশি সাজানো থাকে।

AI-তে সব কিছু — ছবি, শব্দ, embedding, model weight, gradient — শেষ পর্যন্ত সংখ্যার তালিকা। সেই তালিকা দ্রুত process করার জন্য Python-এর built-in list যথেষ্ট নয়। NumPy এই শূন্যস্থান পূরণ করে — C-তে লেখা, SIMDSIMD"Single Instruction, Multiple Data" — একটি CPU instruction একসাথে অনেক সংখ্যায় কাজ করে। NumPy-র অভ্যন্তরীণ ops (BLAS, LAPACK) এই hardware feature ব্যবহার করে $O(n)$ হলেও ১০× constant factor কমায়। ব্যবহারকারী, BLAS/LAPACK-এর সাথে যুক্ত।

কেন NumPy AI-র ভিত্তি

১) Speed: C-implemented, SIMD-aware → list-এর চেয়ে ১০-১০০× দ্রুত।
২) Memory: homogeneous dtype, contiguous block → ৪-৮× কম জায়গা।
৩) API: পুরো PyData ecosystem (PyTorch, TF, scikit-learn, Pandas) — NumPy convention অনুসরণ করে।

২ · ndarray বনাম Python list

Python-এর list একটি generic container — যেকোনো object রাখা যায়। ভেতরে list এক একটি pointer-এর array; প্রতিটি pointer আলাদা স্থানে থাকা PyObject-এ যায়। তাই [1, 2, 3]-এ ১, ২, ৩ — তিনটি আলাদা Python int object — memory-তে scattered।

ndarray উল্টো — সব element একই dtypedtype"data type" — array-এর প্রতিটি element কোন type-এ encoded। int8, int32, int64, float16, float32, float64, bool, complex — common। AI training-এ float32 default, inference-এ float16/int8। (যেমন float32) এবং memory-তে পাশাপাশি (contiguous)। তাই CPU pipeline, cache, SIMD — সব efficient ব্যবহার হয়।

Python list = পাড়ার ১০০টি বাড়িতে ছড়িয়ে থাকা ১০০ জন মানুষ — গুনতে হলে প্রতিটি বাড়িতে যেতে হয়। ndarray = একই train-এ পরপর বসা ১০০ জন — একসাথে গুনে ফেলা যায়।

৩ · Array তৈরি — অনেক উপায়

Python · NumPy
import numpy as np

# Python list থেকে
a = np.array([1, 2, 3, 4])
print("a =", a)

# Predefined patterns
zeros = np.zeros(5)              # [0. 0. 0. 0. 0.]
ones  = np.ones((2, 3))          # 2×3 matrix of 1.0
full  = np.full((2, 2), 7)       # সব 7
eye   = np.eye(3)                # 3×3 identity matrix

# Range-style
r = np.arange(0, 10, 2)          # [0 2 4 6 8]
l = np.linspace(0, 1, 5)         # [0. 0.25 0.5 0.75 1.]

# Random — AI-তে weight init-এ অপরিহার্য
np.random.seed(42)
rand_u = np.random.rand(3)       # uniform [0,1)
rand_n = np.random.randn(3)      # normal (mean 0, std 1)

print("zeros:", zeros)
print("ones:\n", ones)
print("eye:\n", eye)
print("arange:", r)
print("linspace:", l)
print("uniform:", rand_u)
print("normal :", rand_n)

    
np.zeros/ones AI-তে weight initialization-এ; arange/linspace grid তৈরিতে; random.randn normal distribution-এ — যা neural network weight init-এ default (Xavier, He init এর ভিত্তি)। seed দিলে reproducibility।

৪ · Array attributes — পাঁচ চাবি

Python · NumPy
import numpy as np

# একটি 2×3×4 ছবি-আকৃতির array (3 channel, 4 width, etc.)
x = np.zeros((2, 3, 4), dtype=np.float32)

print("shape    :", x.shape)      # (2, 3, 4)
print("ndim     :", x.ndim)       # 3
print("size     :", x.size)       # 24 = 2*3*4
print("dtype    :", x.dtype)      # float32
print("itemsize :", x.itemsize)   # 4 bytes (float32)
print("nbytes   :", x.nbytes)     # 96 = 24 * 4

# Type রূপান্তর
y = x.astype(np.float16)
print("\nfloat16 nbytes:", y.nbytes)   # 48 — অর্ধেক

# Boolean array
mask = np.array([True, False, True])
print("bool itemsize:", mask.itemsize)

    
পাঁচটি core attribute

১) shape — প্রতিটি axis-এর দৈর্ঘ্য (tuple)।
২) ndim — axis-এর সংখ্যা (= len(shape))।
৩) size — মোট element সংখ্যা।
৪) dtype — প্রতিটি element-এর type।
৫) nbytes — মোট memory (= size × itemsize)।

৫ · Reshape, ravel, transpose

Python · NumPy
import numpy as np

a = np.arange(12)                 # 1-D, 12 element
print("original :", a, "shape", a.shape)

# 3×4-এ reshape
b = a.reshape(3, 4)
print("\nreshaped 3x4:\n", b)

# -1 = "তুমি হিসাব করো"
c = a.reshape(2, -1)              # 2×6
print("\n2 x -1 →", c.shape)

# ravel = 1-D করো (view সাধারণত)
flat = b.ravel()
print("\nravel  :", flat)

# Transpose
t = b.T                           # 4×3
print("\nb.T shape:", t.shape)

# 3-D transpose — axis স্পষ্ট দিতে হয়
img = np.zeros((224, 224, 3))     # H × W × C
chw = img.transpose(2, 0, 1)      # C × H × W (PyTorch-এ লাগে)
print("HWC → CHW:", img.shape, "→", chw.shape)

    
reshape data move করে না — শুধু "view" বদলায়। HWC → CHW transpose — image processing-এ TF (channels last) থেকে PyTorch (channels first) convert-এ ব্যবহৃত।

৬ · Vectorization — গতি-গাণিতিক নীতি

একই কাজ — দু'ভাবে করা যায়। Python for-loop, অথবা NumPy vectorized op। সময়ের পার্থক্য অবিশ্বাস্য — complexity একই $O(n)$ হলেও constant factor ১০-১০০×।

Python · NumPy
import numpy as np
import time

n = 1_000_000
xs = list(range(n))
arr = np.arange(n)

# পদ্ধতি ১ — Python for-loop
t0 = time.time()
sq_loop = [x * x for x in xs]
t_loop = time.time() - t0

# পদ্ধতি ২ — NumPy vectorized
t0 = time.time()
sq_np = arr * arr               # পুরো array একসাথে
t_np = time.time() - t0

print(f"Python loop : {t_loop*1000:.2f} ms")
print(f"NumPy vec   : {t_np*1000:.2f} ms")
print(f"Speedup     : {t_loop / max(t_np, 1e-9):.1f}x")

# একই idea — element-wise math
v = np.array([1.0, 4.0, 9.0, 16.0])
print("\nsqrt :", np.sqrt(v))
print("exp  :", np.exp(np.array([0, 1, 2])))
print("sin  :", np.sin(np.array([0, np.pi/2, np.pi])))

    
"For-loop on ndarray" এড়িয়ে চলুন। Element-wise লুপ সরাসরি লিখলে — list-এর চেয়েও ধীর হতে পারে (object box/unbox overhead)। সব সময় whole-array operation, np.where, broadcasting ব্যবহার করুন।

৭ · Aggregation — sum, mean, std সহ axis

Python · NumPy
import numpy as np

# একটি 3×4 মার্ক sheet — 3 ছাত্র, 4 বিষয়
marks = np.array([
    [80, 70, 90, 60],
    [50, 65, 75, 85],
    [95, 88, 70, 92],
])

# পুরো array-এ
print("মোট sum :", marks.sum())
print("গড়     :", marks.mean())
print("std    :", marks.std())
print("min/max:", marks.min(), marks.max())

# axis=0 → column বরাবর (প্রতি বিষয়)
print("\nবিষয়-ওয়ারি গড় :", marks.mean(axis=0))

# axis=1 → row বরাবর (প্রতি ছাত্র)
print("ছাত্র-ওয়ারি গড়  :", marks.mean(axis=1))

# argmax — সর্বোচ্চ কোথায়?
print("\nপ্রতি ছাত্রের সেরা বিষয়:", marks.argmax(axis=1))

    
axis = "যে dimension collapse করব"। axis=0 → row collapse, column গড় থাকে। axis=1 → column collapse, row গড় থাকে। AI-তে batch-wise loss (axis=0), feature-wise mean (axis=0), per-sample sum (axis=1) — সব এই pattern-এ।

৮ · AI-তে ndarray কোথায় ব্যবহার

  • Image: 224×224 RGB ছবি = (224, 224, 3) uint8 ndarray = ~150 KB।
  • Batch tensor: ৩২টি ছবি একসাথে = (32, 3, 224, 224) float32 — GPU-তে এক passa-এ process।
  • Embedding: ১০,০০০ শব্দ × ৭৬৮-D embedding = (10000, 768) matrix।
  • Weight matrix: একটি Linear layer (in=768, out=512) = (768, 512) — প্রায় ৪ লাখ parameter।
  • Gradient: backprop-এ — প্রতি weight-এর gradient সমান shape-এর ndarray।
  • Audio: ১ সেকেন্ড mono audio = (16000,) float32; spectrogram = (time, freq) 2-D।
PyTorch-এর tensor, TensorFlow-এর Tensor, JAX-এর Array — সবাই NumPy-র ndarray-র descendant। API প্রায় একই। NumPy ভালো শিখলে ML framework-এ ঢুকতে দিন তিনেক লাগে।
Memory layout — list বনাম ndarray why ndarray is 10-100x faster 🐌 Python list — scattered list = [ptr, ptr, ptr, ptr] int 1 int 2 int 3 int 4 scattered objects type per element cache-unfriendly ⚡ ndarray — contiguous 1.0 2.0 3.0 4.0 float32 × 4 = 16 bytes ndarray header shape=(4,) dtype=float32 strides=(4,) data=ptr→ one block, one type SIMD + cache friendly 10-100× faster 🤖 AI-তে ব্যবহার image (3, 224, 224) batch (32, 3, 224, 224) embedding (10k, 768) weight (768, 512) gradient — same shape সব input/weight/grad = ndarray (or tensor)
বাঁয়ে — Python list-এর scattered pointer/object। মাঝে — ndarray-এর একটানা memory block + ছোট header। ডানে — AI-তে এই structure সর্বত্র।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ Python list কেন NumPy array-এর তুলনায় ১০-১০০× ধীর? Memory layout, type dispatch, C vs interpreted — তিন দৃষ্টিতে বিশ্লেষণ করুন।

প্রশ্নটি শুধু "speed" নয় — Python-এর design philosophy ও C-extension-এর সম্পর্ক বুঝতে সাহায্য করে। তিনটি ভিন্ন কারণে এই গতির পার্থক্য তৈরি — কোনোটিই algorithm-এর জন্য নয়; দুটি একই কাজে $O(n)$ হলেও constant factor-এ ১০-১০০× তফাত।

(১) Memory layout — scattered বনাম contiguous:

  • Python list = pointer-এর array। প্রতিটি pointer আলাদা স্থানে থাকা PyObject-এ যায়। CPU-কে memory-র এদিক-ওদিক jump করতে হয় — cache miss বেশি।
  • ndarray = একই dtype-এর সংখ্যার একটানা block। CPU-র L1/L2 cache prefetch করতে পারে। এক cache line (৬৪ bytes) = ৮টি float64 বা ১৬টি float32 — সব একসাথে আসে।
  • Cache-friendly access alone ৩-৫× speedup দিতে পারে।

(২) Type dispatch overhead:

  • Python-এ a + b = সাধারণ method call। interpreter দেখবে — a-র type কী, b-র type কী, __add__ খুঁজবে, call করবে, result PyObject wrap করবে।
  • প্রতিটি element-এ এই overhead ~50-100 ns।
  • NumPy arr1 + arr2 = একটি C function call। ভেতরে সরাসরি float* + float* add — কোনো type lookup নেই, কোনো object boxing নেই।

(৩) C vs interpreted execution:

  • Python bytecode interpreter-এ চলে — প্রতিটি op ~১০-১০০ ns overhead।
  • NumPy-র core loop C-তে compiled, GCC দ্বারা optimized।
  • উপরে SIMD (SSE, AVX, NEON) — একটি instruction ৪-১৬টি element একসাথে।
  • BLAS/LAPACK linkage — Intel MKL, OpenBLAS, Apple Accelerate — multi-threaded matrix op।
# বাস্তব benchmark — ১ মিলিয়ন element add
# list comprehension : ~80 ms
# np.array + np.array: ~1.5 ms
# speedup            : ~50×

মূল উপলব্ধি: NumPy "magic" নয় — তিনটি engineering decision-এর ফল: homogeneous dtype + contiguous memory + C/SIMD execution। AI-তে data বিশাল হওয়ায় এই ৫০× কেবল gimmick না — practical viability-র শর্ত। Without NumPy — ChatGPT train করতে দশগুণ সময় ও খরচ।

প্র ০২ dtype কেন গুরুত্বপূর্ণ — float32 vs float64, int8 vs int64? AI training-এ memory ও precision-এর trade-off কীভাবে কাজ করে?

dtype নির্বাচন AI engineering-এ "secret hyperparameter"। সঠিক dtype = ২× কম memory, ২× দ্রুত training, GPU-তে ৪× বেশি batch — কিন্তু ভুল dtype = NaN explosion, training failure।

Common floating-point dtype:

  • float64 (double, 8 bytes): ~১৫-১৬ digit precision। Scientific computing default।
  • float32 (single, 4 bytes): ~৭ digit। AI training-এ default — যথেষ্ট precision, অর্ধেক memory।
  • float16 (half, 2 bytes): ~৩-৪ digit। Inference ও mixed-precision training-এ।
  • bfloat16 (Google, 2 bytes): float32-র range কিন্তু কম mantissa। LLM training-এ এখন standard।
  • float8 / FP8 (1 byte, H100+): সবচেয়ে নতুন — extreme efficiency।

Integer dtype:

  • uint8 (0-255): image pixel-এ আদর্শ।
  • int32 / int64: index, label, count।
  • int8: quantized inference — float32 model কে int8-এ convert করলে ৪× ছোট, ২-৪× দ্রুত।

Memory impact — বাস্তব হিসাব:

# GPT-3 175B parameter
# float32 → 700 GB
# float16 → 350 GB
# int8    → 175 GB  (quantized)
# int4    →  87 GB  (extreme quant)

# 80 GB H100-এ চালানো যায় কি না — dtype-এ নির্ভর

Precision-এর trade-off:

  • Forward pass: float16/bfloat16-এ usually ঠিক। inference-এ লোক float16 ব্যবহার করে।
  • Gradient: ছোট সংখ্যা — float16 underflow হতে পারে (~$10^{-8}$ এর নিচে → 0)। loss scaling দরকার।
  • Optimizer state (Adam moments): usually float32 রাখা — accumulation-এ precision important।
  • Mixed precision (AMP): compute float16, weight master copy float32। PyTorch torch.cuda.amp।

Dtype-related bug — common:

  • uint8 image-এ img + 5 overflow (250 + 10 = 4, না 260)।
  • int division — Python 3-এ / float, কিন্তু NumPy int array-এ সাবধান।
  • Implicit upcast — float32 + float64 = float64, memory দ্বিগুণ unnoticed।

মূল উপলব্ধি: dtype = "memory × precision × speed" এর পদক্ষেপ। AI-তে — training-এ float32/bfloat16, inference-এ float16/int8, image-এ uint8, label-এ int64। ভুল dtype "শুধু slow" নয় — wrong result বা NaN।

প্র ০৩ Vectorization কেন AI-এর মেরুদণ্ড? GPU-তে এই concept কীভাবে scale করে — CUDA, tensor core পর্যন্ত?

Vectorization = "একসাথে অনেক কাজ" — সফটওয়্যার design থেকে hardware architecture পর্যন্ত AI-র সব স্তরে এই ধারণা গাঁথা। বুঝলে — কেন GPU AI-র জন্য এত perfect তাও পরিষ্কার হয়।

স্তরে স্তরে vectorization:

  1. Algorithmic (Python-level): for-loop ছেড়ে whole-array op। complexity একই $O(n)$ কিন্তু interpreter overhead ০।
  2. SIMD (CPU-level): SSE/AVX — একটি 256-bit register-এ ৮টি float32 একসাথে add। NumPy এটা use করে।
  3. Multi-threaded (BLAS-level): OpenBLAS, MKL — matrix op multiple core-এ vector।
  4. SIMT (GPU-level): CUDA — হাজারো thread একই instruction চালায় ভিন্ন data-তে। NVIDIA-র "warp" = ৩২ thread একসাথে।
  5. Tensor core (specialized hardware): NVIDIA Volta (২০১৭+) — একটি cycle-এ একটি ৪×৪ matrix multiply। H100-তে প্রতি cycle ~১০২৪ FLOP।

কেন GPU AI-র জন্য perfect:

  • CPU ~৮-৬৪ core, প্রতিটি smart (branch prediction, OoO execution)।
  • GPU ~১০,০০০ tiny core — সব একই instruction চালায় (SIMT)।
  • AI workload — same op (matrix mul, conv) on huge data = perfect vectorization fit।
  • একটি matrix multiply = লক্ষ-কোটি independent multiply-add → GPU-তে parallel।

Real numbers:

# GPT-3 training
# Python loop: feasible না (years)
# NumPy CPU  : ~মাস
# CUDA GPU   : ~সপ্তাহ
# Tensor core: ~দিন

Vectorization-এর শর্ত:

  • Independent operations: $y_i = f(x_i)$ — $y_{i-1}$-এর উপর নির্ভর করলে vectorize কঠিন।
  • Regular memory access: stride pattern simple।
  • Same operation: branching কম — branch mismatch → SIMT efficiency ৫০% হারায়।

AI architecture vectorization-friendly করে:

  • Matrix multiply — embarrassingly parallel।
  • Convolution — same kernel, ভিন্ন position।
  • Attention — Q@K matmul, softmax, V@... — সব dense matmul।
  • RNN sequential — তাই Transformer ৪× বেশি GPU-friendly, ফলে winner।

মূল উপলব্ধি: NumPy-তে শেখা vectorization habit — এক skill যা GPU programming, CUDA, JAX, এমনকি future neuromorphic chip-এ পর্যন্ত transfer হয়। "Avoid loops, embrace arrays" — AI engineer-এর প্রথম mantra। আজকের LLM revolution মূলত vectorization revolution-এর extension।

প্র ০৪ NumPy আজও কেন প্রাসঙ্গিক — PyTorch/TensorFlow থাকা সত্ত্বেও? Interop, prototyping, ecosystem — তিন দৃষ্টিতে।

২০০৬-এ Travis Oliphant-এর তৈরি NumPy আজও AI stack-এর মূল। ১৮ বছর পর — DL framework-এর যুগে — কেন এটা মরে যায়নি? কারণ NumPy কেবল লাইব্রেরি না; এটি একটি convention।

(১) Interop — সবার সাধারণ ভাষা:

  • PyTorch tensor-কে NumPy-তে: tensor.numpy()
  • NumPy থেকে PyTorch: torch.from_numpy(arr)
  • TensorFlow, JAX, CuPy — সবাই NumPy API mimic করে।
  • Pandas DataFrame-এর underlying = NumPy array।
  • scikit-learn input/output = NumPy array।
  • Matplotlib plot input = NumPy array।
  • OpenCV image = NumPy uint8 array।
  • PIL image → np.asarray(img) = standard bridge।

NumPy = PyData ecosystem-এর "lingua franca"। যেকোনো দু'টি library-কে যুক্ত করতে — মাঝে NumPy।

(২) Prototyping — দ্রুত পরীক্ষা:

  • GPU দরকার নেই — CPU-তে চলে।
  • Eager execution — কোনো graph compile না।
  • Jupyter-এ instant feedback।
  • Algorithm prototype করতে — Pure NumPy-তে লেখা সবচেয়ে clear।
  • সব ML paper-এর pseudocode কাছাকাছি = NumPy syntax।

একটি নতুন idea — NumPy-তে first prototype, তারপর PyTorch port — এই workflow আজও standard।

(৩) Ecosystem — ২০ বছরের dependency tree:

  • SciPy — scientific computing, NumPy-র উপর।
  • Pandas — DataFrame, সব underlying NumPy।
  • scikit-learn — classical ML, NumPy-centric।
  • statsmodels, NetworkX, Astropy, Biopython — সবাই NumPy।
  • হাজার hazaar paper-এর code repository — NumPy-র উপর।

এই ecosystem replace করা practically impossible।

NumPy-র সীমা — যেখানে DL framework দরকার:

  • GPU support নেই (CuPy/JAX এই গর্ত পূরণ করে)।
  • Automatic differentiation নেই (autograd dorkar)।
  • Production deployment — torch script, TF SavedModel।
  • Distributed training।

NumPy 2.0 (২০২৪) — নতুন প্রাণ:

  • Cleaner API, bool/string dtype improvements।
  • Array API standard — JAX/PyTorch/CuPy compatible interface।
  • "Array API" = সব framework-এর জন্য common subset → portable code।

মূল উপলব্ধি: NumPy "old" না — "foundational"। PyTorch ছাড়া AI possible, NumPy ছাড়া না। নতুন framework আসে, পুরোনো যায় — NumPy থাকে। AI engineer হিসেবে — আগে NumPy ভালো করে শিখুন, তারপর যেকোনো DL framework দিন তিনেক-এ।

অনুশীলন

  1. Array তৈরি ও attribute: একটি $4 \times 5$ float32 array তৈরি করুন যা সব 3.14-এ পূর্ণ। তারপর shape, dtype, nbytes print করুন।
    import numpy as np
    
    arr = np.full((4, 5), 3.14, dtype=np.float32)
    print("shape :", arr.shape)      # (4, 5)
    print("dtype :", arr.dtype)      # float32
    print("nbytes:", arr.nbytes)     # 80  = 4*5*4
    print("size  :", arr.size)       # 20
  2. Vectorization বনাম loop: ১ থেকে ১,০০,০০০ পর্যন্ত সংখ্যার বর্গের যোগফল দু'ভাবে — Python loop ও NumPy দিয়ে — হিসাব করুন।
    import numpy as np
    import time
    
    n = 100_000
    
    # Python loop
    t0 = time.time()
    s_loop = sum(i * i for i in range(1, n + 1))
    print(f"loop : {s_loop}, {(time.time()-t0)*1000:.2f} ms")
    
    # NumPy vectorized
    t0 = time.time()
    arr = np.arange(1, n + 1)
    s_np = (arr * arr).sum()
    print(f"numpy: {s_np}, {(time.time()-t0)*1000:.2f} ms")

    NumPy version ১০-৫০× দ্রুত হবে। দু'টি একই উত্তর দেবে।

  3. Reshape ও aggregation: np.arange(24) থেকে $2 \times 3 \times 4$ shape-এর array বানান। প্রতিটি axis-এ sum বের করুন।
    import numpy as np
    
    a = np.arange(24).reshape(2, 3, 4)
    print("shape :", a.shape)        # (2, 3, 4)
    print("sum total :", a.sum())    # 276
    
    print("axis=0  :", a.sum(axis=0).shape, a.sum(axis=0))
    print("axis=1  :", a.sum(axis=1).shape)
    print("axis=2  :", a.sum(axis=2).shape)
    # axis=0 → (3, 4)
    # axis=1 → (2, 4)
    # axis=2 → (2, 3)

    মনে রাখবেন: axis collapse হয় — যে axis দিচ্ছেন সেটা output shape থেকে চলে যাবে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন — Google-এর ফ্রি অনলাইন Python পরিবেশ, শুধু Gmail অ্যাকাউন্ট লাগে। NumPy preinstalled।
পূর্ববর্তী পাঠ
পাঠ ০৮ · Error handling ও exception