Indexing va slicing: kerakli bo'lakni olish
Sahna: haftalik savdo jadvali
Do'kon tarmog'ida 4 filial, har biri uchun 7 kunlik savdo (million so'mda). Savollar har kuni boshqa: "2-filialning shanba kungi savdosi?", "hamma filialning dushanbasi?", "50 dan past kunlar qaysi?". Har savol — jadvaldan bitta bo'lak olish. Bu bobning ishi shu.
import numpy as np rng = np.random.default_rng(3) kunlar = np.array(["Du", "Se", "Ch", "Pa", "Ju", "Sh", "Ya"]) filiallar = np.array(["Chilonzor", "Yunusobod", "Sergeli", "Olmazor"]) savdo = rng.integers(30, 90, size=(4, 7)) print(savdo) print(savdo.shape)
[[78 35 40 44 40 78 82] [64 32 35 49 55 67 58] [45 39 71 74 31 36 57] [53 83 61 55 55 69 65]] (4, 7)
Qatorlar — filiallar (axis 0), ustunlar — kunlar (axis 1).
Bitta element va bitta qator
print(savdo[1, 5]) print(savdo[1]) print(savdo[-1, -1])
67 [64 32 35 49 55 67 58] 65
savdo[1, 5]— 1-qator, 5-ustun: Yunusobod, shanba. Indeks 0 dan boshlanadi: 0-qator — Chilonzor.savdo[1]— butun 1-qator: Yunusobod ning haftasi.-1— oxiridan birinchi: oxirgi filial, oxirgi kun. Uzunlikni bilmasangiz ham oxirgisini olasiz.
savdo[1][5] ham ishlaydi, lekin u ikki qadam: avval qator nusxasini yasaydi, keyin undan oladi. savdo[1, 5] — bitta qadam va har doim to'g'ri usul.
Slicing: oraliq olish
![Qaysi kataklar tanlanadi: a[1], a[:, 2], a[0:2, 1:3], a[::2, ::2]](/rasm/bob/numpy-pandas-03-1.webp)
Qaysi kataklar tanlanadi: a[1], a[:, 2], a[0:2, 1:3], a[::2, ::2]
Qoida Python ro'yxatidagi bilan bir xil — start:stop:step, stop kirmaydi — faqat har o'q uchun alohida, vergul bilan:
print("dushanba, hamma filial:", savdo[:, 0]) print("Chilonzor, ish kunlari:", savdo[0, :5]) print("dam olish kunlari:\n", savdo[:, 5:]) print("har ikkinchi kun:", kunlar[::2])
dushanba, hamma filial: [78 64 45 53] Chilonzor, ish kunlari: [78 35 40 44 40] dam olish kunlari: [[78 82] [67 58] [36 57] [69 65]] har ikkinchi kun: ['Du' 'Ch' 'Ju' 'Ya']
: yolg'iz — "shu o'q bo'yicha hammasi". savdo[:, 0] — barcha qatorlar, 0-ustun. 5: — 5 dan oxirigacha.
View va copy: eng xavfli farq
Slicing ma'lumotni ko'chirmaydi. U asl array ga boshqa "deraza" ochadi — view. Derazadan o'zgartirsangiz, asl ham o'zgaradi.

Slice view beradi va asl o'zgaradi; ro'yxat bilan indekslash copy beradi
a = np.array([10, 20, 30, 40, 50]) b = a[1:3] b[0] = 99 print("slice dan keyin a:", a, "| xotira umumiy:", np.shares_memory(a, b)) a = np.array([10, 20, 30, 40, 50]) c = a[[1, 2]] c[0] = 99 print("ro'yxat bilan keyin a:", a, "| xotira umumiy:", np.shares_memory(a, c)) d = a[1:3].copy() print("copy() bilan xotira umumiy:", np.shares_memory(a, d))
slice dan keyin a: [10 99 30 40 50] | xotira umumiy: True ro'yxat bilan keyin a: [10 20 30 40 50] | xotira umumiy: False copy() bilan xotira umumiy: False
Nega NumPy shunday qilgan? Tezlik uchun: million qatorli jadvaldan yarmini olish ma'lumotni ko'chirmasdan bir lahzada bo'ladi. Narxi — kutilmagan o'zgarish. Qoida: kesib olgan bo'lakni o'zgartirmoqchi bo'lsangiz, .copy() yozing. np.shares_memory — shubha bo'lsa tekshirish usuli.
Fancy indexing: ro'yxat bilan tanlash
Ketma-ket bo'lmagan qatorlar kerak bo'lsa, indekslar ro'yxatini berasiz. Natija har doim copy.
print(filiallar[[0, 2]]) print(savdo[[0, 2], 5]) print(savdo[:, [0, 6]])
['Chilonzor' 'Sergeli'] [78 36] [[78 82] [64 58] [45 57] [53 65]]
Boolean mask: shart bilan tanlash
Eng kuchli usul — "qaysi o'rinda" emas, "qanday shartda" tanlash.
past = savdo < 45 print(past.astype(int)) print("45 dan past kunlar soni:", past.sum()) print("o'sha qiymatlar:", savdo[past])
[[0 1 1 1 1 0 0] [0 1 1 0 0 0 0] [0 1 0 0 1 1 0] [0 0 0 0 0 0 0]] 45 dan past kunlar soni: 9 o'sha qiymatlar: [35 40 44 40 32 35 39 31 36]
savdo < 45 — xuddi shu shakldagi True/False jadval (mask). savdo[past] — faqat True joylardagi sonlar, 1 o'lchamli ro'yxat bo'lib chiqadi: jadval shakli saqlanmaydi, chunki har qatorda har xil sonda True bor.
Bir nechta shart — & (va), | (yoki), ~ (emas), har shart qavsda:
dam = np.isin(kunlar, ["Sh", "Ya"]) print("dam olish kunlari maskasi:", dam) yaxshi_dam = (savdo > 70) & dam print("dam olish kunida 70 dan yuqori:", savdo[yaxshi_dam]) qator, ustun = np.nonzero(yaxshi_dam) for q, u in zip(qator, ustun): print(f" {filiallar[q]}, {kunlar[u]}: {savdo[q, u]}")
dam olish kunlari maskasi: [False False False False False True True] dam olish kunida 70 dan yuqori: [78 82] Chilonzor, Sh: 78 Chilonzor, Ya: 82
Python ning and va or so'zlari bu yerda ishlamaydi: ular butun massivni bitta True/False ga aylantirishga urinadi va xato beradi. Massivlar uchun — & va |.
np.nonzero maskadan qaysi o'rinlar True ekanini qaytaradi — shunda "qaysi filial, qaysi kun" degan savolga javob beramiz.
Mask bilan o'zgartirish
Mask faqat o'qish uchun emas. Kassa xatosi bilan manfiy yozilgan summalarni nolga aylantirish:
yozuv = np.array([120, -5, 87, -40, 230]) yozuv[yozuv < 0] = 0 print(yozuv) print(np.where(savdo[0] >= 60, "yaxshi", "past"))
[120 0 87 0 230] ['yaxshi' 'past' 'past' 'past' 'past' 'yaxshi' 'yaxshi']
yozuv[yozuv < 0] = 0 — "shart bajarilgan joylarga 0 yoz". np.where(shart, A, B) esa asl massivni o'zgartirmaydi: shart rost joyga A, yolg'on joyga B qo'yib, yangi massiv qaytaradi.
Rasmda: haftaning issiqlik xaritasi
Indekslash nimani tanlayotganini ko'rish uchun butun jadvalni rang bilan chizamiz va mask tanlagan kataklarni belgilaymiz:
fig, ax = plt.subplots(figsize=(8, 3.6)) rasm = ax.imshow(savdo, cmap="YlGn") ax.set_xticks(range(7), kunlar) ax.set_yticks(range(4), filiallar) for q, u in zip(*np.nonzero(past)): ax.text(u, q, savdo[q, u], ha="center", va="center", color="#c5221f", weight="bold") fig.colorbar(rasm, label="mln so'm") ax.set_title("Qizil raqam — 45 dan past kunlar (mask)") plt.show()

Jadvalni rasm sifatida ko'rish — katta array da qayerda nima borligini tez tushunishning eng oson yo'li. 3-qismda bu usulni Matplotlib bilan chuqurroq o'rganamiz.
Xulosa
a[q, u]— bitta element;a[q]— qator;a[:, u]— ustun; manfiy indeks oxiridan sanaydi.- Slice
start:stop:step,stopkirmaydi; har o'q uchun vergul bilan. - Slice — view (asl bilan bir xotira); ro'yxat bilan indekslash va
.copy()— copy. Shubha bo'lsa —np.shares_memory. - Boolean mask: shart bilan tanlash; shartlar
&,|,~va qavslar bilan. a[mask] = qiymataslni o'zgartiradi;np.whereyangi massiv qaytaradi.
Mashqlar
savdodan Sergeli filialining payshanbadan yakshanbagacha savdosini oling.x = np.arange(10),y = x[::2],y[:] = 0.xqanday bo'ladi? Avval taxmin qiling.- Har filialning eng yaxshi kunini toping (maslahat:
argmax, 5-bobda batafsil). - 50 dan past yoki 80 dan yuqori bo'lgan kunlar nechta?
Javoblar
savdo[2, 3:]— Pa, Ju, Sh, Ya.[0 1 0 3 0 5 0 7 0 9]:y— view, unga yozishxning juft o'rinlarini o'zgartiradi.kunlar[savdo.argmax(axis=1)]— har qator bo'yicha eng katta qiymat o'rni.((savdo < 50) | (savdo > 80)).sum().
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.