Indexing and slicing — basic, boolean masking, fancy indexing
1. Basic slicing — start:stop:step
WHAT it returns: a view — a new array object that shares the same data buffer. Mutating the slice mutates the original.
WHY a view (HOW it works): A slice just changes the offset and strides of the recipe; no data is copied. That's why it's instant even for huge arrays.
2. Boolean masking — select by a condition
WHY a copy: the selected elements are scattered irregularly in memory; you can't describe them with a single stride, so NumPy must gather them into fresh contiguous memory.
3. Fancy (integer-array) indexing — select by position list

Recall Feynman: explain to a 12-year-old
Imagine a long row of numbered lockers full of toys.
- Slicing = "open lockers 2 through 8, skipping every other one." Fast, and you're looking at the real lockers — move a toy and it's really moved.
- Boolean masking = you have a checklist: tick the lockers that hold a red toy, then copy just those toys into a basket.
- Fancy indexing = you hand a list "lockers 5, 1, 1, 3 please" and get those toys in that order, even repeats. Masking and the list make a basket (copy); the range just peeks at the real lockers (view).
Flashcards
What three ways can you index a NumPy array?
start:stop:step), boolean masking, fancy (integer-array) indexing.Does basic slicing return a view or a copy?
Do boolean masking and fancy indexing return a view or a copy?
Why must you use &, |, ~ instead of and, or, not in a mask?
and/or need a single boolean and raise an ambiguity error.Formula for the length of a[start:stop:step] (step>0)?
What does A[[0,2],[1,3]] return for a 2-D A?
A[0,1] and A[2,3] — NOT a 2×2 block.How do you select the actual block of rows {0,2} × cols {1,3}?
A[np.ix_([0,2],[1,3])].What shape does a[idx] have when idx is a 2×2 integer array?
idx (2×2); fancy indexing follows the index array's shape.What does a boolean mask do to the dimensionality of a 2-D array?
How to safely edit the first row of A without changing A?
b = A[0].copy().Connections
- NumPy arrays — shape, strides, dtype (why views are cheap)
- Broadcasting (masks/index arrays broadcast to array shape)
- Views vs Copies — memory model
- np.where and conditional selection
- Vectorization — replacing Python loops
- Pandas .loc / .iloc indexing (same ideas at DataFrame level)
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, NumPy array bas memory me numbers ki ek line hai, aur ek "recipe" (shape + strides) jo batati hai kaunsa element kahan rakha hai. Element(s) maangne ke teen tareeke hain. Pehla basic slicing — a[start:stop:step], yaani ek range. Ye view deta hai, matlab original memory hi share karta hai — agar slice me kuch change karoge to original array bhi badal jayega. Isliye fast hai, copy nahi banati.
Doosra boolean masking — ek True/False array banao (jaise a > 0), aur a[mask] sirf wahi elements deta hai jahan True hai. Ye ek copy hai aur hamesha 1-D ho jaata hai. Yaad rakho conditions jodne ke liye &, |, ~ use karo, and/or nahi — kyunki yahan har element pe alag-alag operation chahiye, aur har condition ko bracket me daalna padta hai.
Teesra fancy indexing — seedha positions ki list do, a[[3,0,0,2]] — jo order maango wahi milega, repeat bhi chalega. Ye bhi copy hai aur result ka shape index array ke shape jaisa banta hai. Bada trap: A[[0,2],[1,3]] 2×2 block nahi deta — wo (0,1) aur (2,3) ko pair karke deta hai. Block chahiye to np.ix_ use karo.
Kyun important hai? Kyunki ye sab vectorized hai — Python ka slow for loop hatao, ek line me lakhon elements filter/reorder karo. 80/20 funda: bas "view vs copy" aur "fancy index pointwise zip hota hai" ye do cheezein pakad lo, baaki sab samajh aa jayega.