IlmHamroh
Python kursi/Malumot tahlili4/18-dars16 daqiqa
Mundarija (22)

24.4-dars: NumPy — unumdorlik

24-QISM — MA'LUMOT TAHLILI · 4-dars


1. Kirish va motivatsiya

24.1–24.3 da NumPy'ning imkoniyatlarini ko'rdik. Endi eng muhim savol: nega NumPy tez va uni qanday yanada tezroq, kam xotira bilan ishlatish mumkin? Katta ma'lumot (million, milliard element) bilan ishlaganda bu farq hal qiluvchi: sekin kod soatlab kutish, tez kod soniyalar. Xotira ham muhim: noto'g'ri dtype xotirani 8 barobar ko'p ishlatishi mumkin.

NumPy unumdorligi uch tamoyilga asoslanadi: vektorlashtirish (sikl o'rniga massiv amali — C darajasida), to'g'ri dtype (element turi — int8 vs int64 xotirani 8 barobar farq qiladi), nusxasizlik (view — ko'chirmaslik). Bularni tushunish — katta ma'lumot bilan samarali ishlashning kaliti. pandas 24.12-bob, ML (25) da bu bilim to'g'ridan-to'g'ri qo'l keladi.

Real vaziyat. Bir tahlil 50 million qatorni qayta ishlardi — Python sikl bilan 4 daqiqa, xotira 4GB. Ikki o'zgarish: vektorlashtirish (sikl → massiv amali) va dtype (int64 → int32, kerak emas edi) — 2 soniya, 2GB. 120 barobar tez, 2 barobar kam xotira. Vektorlashtirish va dtype — katta ma'lumot bilan ishlashning asosi.

Bu darsda NumPy unumdorligi — vektorlashtirish, dtype, xotirani o'rganamiz.

Bu darsda:

  • Nega NumPy tez
  • Vektorlashtirish (sikl o'rniga)
  • dtype va xotira
  • astype (tur o'zgartirish)
  • Joyida amal (in-place)
  • View — nusxasiz tezlik
  • Unumdorlik o'lchash
  • Amaliy: samarali hisoblash

ℹ Misollarda NumPy (import numpy as np) bilan sinaladi.


2. Nazariya — chuqur tushuntirish

2.1. Nega NumPy tez

NumPy uch sabab bilan tez:

1. Uzluksiz xotira (C massivi — kesh samarali)
2. Bir tur (dtype — tekshirish yo'q)
3. Vektorlangan (C darajasida amal, Python sikl emas)

NumPy tezligi uch tamoyil: 1) ma'lumot uzluksiz xotirada (C massivi — protsessor keshi tez o'qiydi; ro'yxat tarqoq), 2) bir tur (dtype — har amalda tur tekshirish kerak emas), 3) amal C darajasida (kompilyatsiyalangan, Python sikl emas). Natija: Python sikldan 10–100 barobar tez. Bu ma'lumotga yo'naltirilgan dizayn 24.1-bob.

2.2. Vektorlashtirish (sikl o'rniga)

Vektorlashtirish — sikl o'rniga massiv amali:

python
# ⚠️ sekin (Python sikl):
natija = np.zeros(len(a))
for i in range(len(a)):
    natija[i] = a[i] * 2 + 1

# ✅ tez (vektorlangan):
natija = a * 2 + 1

Vektorlashtirish — Python sikl (for) o'rniga butun massiv amali (a * 2 + 1). Sikl har elementni Python darajasida qayta ishlaydi (sekin); vektorlangan amal butun massivni C darajasida (tez). Natija bir xil, lekin tezlik 10–100 barobar. Qoida: massivda sikl ko'rsangiz — vektorlashtirishga harakat qil.

2.3. dtype va xotira

dtype xotirani belgilaydi:

dtype Bayt (element) Oraliq
int8 1 -128 … 127
int16 2 ±32768
int32 4 ±2 milliard
int64 8 juda katta
float32 4 o'nli (kam aniq)
float64 8 o'nli (aniq)

dtype — element turi va xotira hajmi: int8 (1 bayt), int64 (8 bayt) — 8 barobar farq. Million element: int8 = 1MB, int64 = 8MB. To'g'ri dtype tanlash xotirani tejaydi: kichik sonlarga int8/int16, oddiy o'nli float32. .itemsize (bir element bayt), .nbytes (jami). Katta ma'lumotda muhim.

2.4. astype (tur o'zgartirish)

Massiv turini o'zgartirish:

python
a = np.array([1.9, 2.1, 3.8])
a.astype(np.int32)         # [1 2 3] (float → int, kesiladi)
b = np.array([1, 2, 3])
b.astype(np.float64)       # [1. 2. 3.]
katta.astype(np.int32)     # int64 → int32 (xotira yarmi)

astype(dtype) — massiv turini o'zgartiradi (yangi massiv — nusxa). float → int (kasr kesiladi, yaxlitlamaydi — 1.9 → 1). int64 → int32 (xotira yarmi, lekin oraliq kichrayadi). Ma'lumotni tayyorlash (model kirishi), xotira tejashda kerak. Ehtiyot: oraliq va aniqlik yo'qolishi mumkin.

2.5. Joyida amal (in-place)

Yangi massiv yaratmasdan o'zgartirish:

python
a *= 2                     # joyida (yangi massiv yo'q)
a += 10
np.multiply(a, 2, out=a)   # natija a ga (out)
# vs:
a = a * 2                  # yangi massiv (xotira ko'p)

Joyida amal (in-place) — a *= 2, a += 10 — massivni o'zi ustida o'zgartiradi (yangi massiv yaratmaydi — xotira tejaydi). a = a * 2 esa yangi massiv yaratadi (eski + yangi = ikki barobar xotira). Katta massivda joyida amal xotirani tejaydi. out= parametri — natijani mavjud massivga. Ehtiyot: joyida amal aslni o'zgartiradi.

2.6. View — nusxasiz tezlik

View 24.3-bob unumdorlik beradi:

python
b = a[1:1000000]           # view (nusxa yo'q — tez)
b = a[1:1000000].copy()    # nusxa (xotira + vaqt)
a.reshape(1000, 1000)      # odatda view (nusxa yo'q)
a.T                        # transpoz — view

View 24.3-bob — nusxasiz (asl bilan bir xotira) — tez va xotira tejaydi. Kesish, reshape, .T — odatda view (nusxa yo'q). .copy() — nusxa (kerak bo'lganda). Katta massivda keraksiz nusxa — xotira va vaqt isrofi. Qoida: nusxa faqat kerak bo'lganda (.copy()), aks holda view (tez).

2.7. Unumdorlik o'lchash

Tezlikni o'lchash:

python
import time
boshi = time.perf_counter()
natija = a * 2 + 1
print(time.perf_counter() - boshi)

# yoki timeit:
# %timeit a * 2 + 1        (Jupyter)
import timeit
timeit.timeit(lambda: a * 2, number=100)

Unumdorlikni o'lchab tekshir (taxmin qilmasdan): time.perf_counter() (aniq vaqt), timeit (ko'p marta o'rtacha — aniqroq), Jupyter'da %timeit. "O'lchamasdan optimallashtirma" — avval o'lcha, keyin tuzat 29.1-bob. Ko'pincha kutilmagan joy sekin bo'ladi. O'lchash — optimallashtirishning birinchi qadami.

2.8. Unumdorlik tamoyillari

NumPy unumdorlik tamoyillari: 1) vektorlashtir (sikl o'rniga massiv amali — eng katta ta'sir), 2) to'g'ri dtype (xotira — int8 vs int64), 3) nusxani kamaytir (view, joyida amal), 4) o'lcha (taxmin emas). "Avval to'g'ri, keyin tez" — avval ishlaydigan kod, keyin (o'lchab) tez. Katta ma'lumotda bu farq soatlar vs soniyalar. NumPy'ni to'g'ri ishlatish — ma'lumot muhandisligining asosi.


3. Tez ma'lumotnoma

python
import numpy as np

# vektorlashtirish (sikl o'rniga):
natija = a * 2 + 1           # ✅ (for emas)

# dtype va xotira:
a = np.array([...], dtype=np.int32)
a.itemsize                   # bir element bayt
a.nbytes                     # jami bayt
a.astype(np.float32)         # tur o'zgartirish (nusxa)

# joyida amal (xotira tejaydi):
a *= 2; a += 10              # ✅ (yangi massiv yo'q)
np.multiply(a, 2, out=a)

# view (nusxasiz):
b = a[1:1000]                # view (tez)
b = a[1:1000].copy()         # nusxa (kerak bo'lsa)

# o'lchash:
import timeit
timeit.timeit(lambda: a * 2, number=100)

Unumdorlik xulosasi

Vektorlashtir: sikl → massiv amali (10-100x) · dtype: xotira (int8 vs int64)
astype: tur o'zgartir · joyida (*=): xotira tejaydi · view: nusxasiz
O'lcha (timeit), taxmin qilma

4. Batafsil misollar

Misollarda NumPy (import numpy as np) bilan sinaladi. Tezlik vaqti mashinaga bog'liq (bu yerda o'lchanmaydi); xotira (nbytes) va natija to'g'riligi ko'rsatiladi.

Misol 1 — Vektorlashtirish (sikl vs massiv)

python
"""vektorlashtirish: Python sikl va massiv amali bir xil natija beradi (lekin massiv tez)."""

import numpy as np


def main() -> None:
    a = np.arange(1, 8)

    print("=== 1. Python sikl (sekin) ===")
    sikl_natija = np.zeros(len(a), dtype=int)
    for i in range(len(a)):
        sikl_natija[i] = a[i] * 2 + 1
    print(f"  sikl: {sikl_natija.tolist()}")

    print("\n=== 2. Vektorlangan (tez) ===")
    vek_natija = a * 2 + 1
    print(f"  vektorlangan: {vek_natija.tolist()}")

    print("\n=== 3. Natija bir xil ===")
    print(f"  teng: {np.array_equal(sikl_natija, vek_natija)}")

    print("\n=== 4. Murakkab amal (vektorlangan) ===")
    b = np.arange(1, 6)
    natija = np.sqrt(b) + b ** 2
    print(f"  sqrt(b)+b^2 = {np.round(natija, 3).tolist()}")
    print("  ⭐ vektorlangan — sikl bilan bir xil natija, lekin tez")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Python sikl (sekin) ===
  sikl: [3, 5, 7, 9, 11, 13, 15]

=== 2. Vektorlangan (tez) ===
  vektorlangan: [3, 5, 7, 9, 11, 13, 15]

=== 3. Natija bir xil ===
  teng: True

=== 4. Murakkab amal (vektorlangan) ===
  sqrt(b)+b^2 = [2.0, 5.414, 10.732, 18.0, 27.236]
  ⭐ vektorlangan — sikl bilan bir xil natija, lekin tez

Nima ko'rsatdi: 2.1, 2.2-bo'limlar.

Misol 2 — dtype va xotira

python
"""dtype: itemsize (element bayt), nbytes (jami); int8 vs int64 — xotira 8 barobar farq."""

import numpy as np


def main() -> None:
    print("=== 1. Turli dtype — element bayti ===")
    for dt in [np.int8, np.int16, np.int32, np.int64]:
        a = np.ones(100, dtype=dt)
        print(f"  {np.dtype(dt).name}: itemsize={a.itemsize} bayt, nbytes(100)={a.nbytes}")

    print("\n=== 2. float turlari ===")
    for dt in [np.float32, np.float64]:
        a = np.ones(100, dtype=dt)
        print(f"  {np.dtype(dt).name}: itemsize={a.itemsize} bayt")

    print("\n=== 3. Xotira taqqoslash (1 million element) ===")
    n = 1_000_000
    print(f"  int8:  {np.ones(n, dtype=np.int8).nbytes:>9} bayt (~1 MB)")
    print(f"  int64: {np.ones(n, dtype=np.int64).nbytes:>9} bayt (~8 MB)")

    print("\n=== 4. dtype oraligi ===")
    print(f"  int8 oraliq: {np.iinfo(np.int8).min} … {np.iinfo(np.int8).max}")
    print(f"  int32 max: {np.iinfo(np.int32).max}")
    print("  ⭐ to'g'ri dtype — xotirani tejaydi (int8 vs int64: 8x)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Turli dtype — element bayti ===
  int8: itemsize=1 bayt, nbytes(100)=100
  int16: itemsize=2 bayt, nbytes(100)=200
  int32: itemsize=4 bayt, nbytes(100)=400
  int64: itemsize=8 bayt, nbytes(100)=800

=== 2. float turlari ===
  float32: itemsize=4 bayt
  float64: itemsize=8 bayt

=== 3. Xotira taqqoslash (1 million element) ===
  int8:    1000000 bayt (~1 MB)
  int64:   8000000 bayt (~8 MB)

=== 4. dtype oraligi ===
  int8 oraliq: -128 … 127
  int32 max: 2147483647
  ⭐ to'g'ri dtype — xotirani tejaydi (int8 vs int64: 8x)

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — astype, joyida amal, view

python
"""astype (tur o'zgartirish, kesish); joyida amal (*=); view vs copy (base)."""

import numpy as np


def main() -> None:
    print("=== 1. astype (float → int, kesiladi) ===")
    a = np.array([1.9, 2.1, 3.8, 4.5])
    print(f"  {a.tolist()} → int: {a.astype(np.int32).tolist()}")

    print("\n=== 2. astype (int → float) ===")
    b = np.array([1, 2, 3])
    print(f"  {b.tolist()} → float: {b.astype(np.float64).tolist()}")

    print("\n=== 3. Joyida amal (*=) ===")
    c = np.arange(5)
    c *= 2                          # joyida (yangi massiv yo'q)
    c += 1
    print(f"  c*=2, c+=1 → {c.tolist()}")

    print("\n=== 4. View vs copy (base) ===")
    x = np.arange(10)
    view = x[2:6]
    nusxa = x[2:6].copy()
    print(f"  view base asl massivmi: {view.base is x}")
    print(f"  copy base None (mustaqil): {nusxa.base is None}")
    print("  ⭐ astype (tur), joyida (*=) xotira tejaydi, view nusxasiz")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. astype (float → int, kesiladi) ===
  [1.9, 2.1, 3.8, 4.5] → int: [1, 2, 3, 4]

=== 2. astype (int → float) ===
  [1, 2, 3] → float: [1.0, 2.0, 3.0]

=== 3. Joyida amal (*=) ===
  c*=2, c+=1 → [1, 3, 5, 7, 9]

=== 4. View vs copy (base) ===
  view base asl massivmi: True
  copy base None (mustaqil): True
  ⭐ astype (tur), joyida (*=) xotira tejaydi, view nusxasiz

Nima ko'rsatdi: 2.4, 2.5, 2.6-bo'limlar.

Misol 4 — Amaliy: katta ma'lumot samarali ishlash

Real misol: katta massiv — vektorlangan hisoblash, to'g'ri dtype, joyida amal (xotira tejash). Bu — samarali ma'lumot ishlashning namunasi.

python
"""to'liq samaradorlik: to'g'ri dtype (int16), vektorlangan hisoblash, joyida amal, xotira taqqos."""

import numpy as np


def main() -> None:
    # 100000 talaba bahosi (0-100 — int8 yetarli)
    n = 100_000
    rng = np.arange(n) % 101      # 0-100 takrorlanadigan (deterministik)

    print("=== 1. To'g'ri dtype (baho 0-100 → int8) ===")
    baholar = rng.astype(np.int8)
    print(f"  {n} baho, dtype={baholar.dtype}, xotira={baholar.nbytes} bayt")
    print(f"  int64 bo'lsa: {n * 8} bayt (8x ko'p)")

    print("\n=== 2. Vektorlangan statistika ===")
    print(f"  o'rtacha: {round(float(baholar.mean()), 2)}")
    print(f"  o'tganlar (60+): {(baholar >= 60).sum()}")

    print("\n=== 3. Vektorlangan tuzatish (5 ball, chekla) ===")
    tuzatilgan = np.clip(baholar.astype(np.int16) + 5, 0, 100)
    print(f"  tuzatilgandan keyin o'rtacha: {round(float(tuzatilgan.mean()), 2)}")

    print("\n=== 4. Joyida amal (xotira tejash) ===")
    ball = np.ones(n, dtype=np.int32)
    ball *= 10                     # joyida (yangi massiv yo'q)
    print(f"  joyida *10: har element = {ball[0]}, jami = {ball.sum()}")
    print("  ⭐ dtype + vektorlangan + joyida — katta ma'lumot samarali")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. To'g'ri dtype (baho 0-100 → int8) ===
  100000 baho, dtype=int8, xotira=100000 bayt
  int64 bo'lsa: 800000 bayt (8x ko'p)

=== 2. Vektorlangan statistika ===
  o'rtacha: 50.0
  o'tganlar (60+): 40590

=== 3. Vektorlangan tuzatish (5 ball, chekla) ===
  tuzatilgandan keyin o'rtacha: 54.85

=== 4. Joyida amal (xotira tejash) ===
  joyida *10: har element = 10, jami = 1000000
  ⭐ dtype + vektorlangan + joyida — katta ma'lumot samarali

Nima ko'rsatdi: 2.1–2.8-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"NumPy sikl ham tez" Sikl sekin (vektorlashtir)
"dtype muhim emas" Xotira (int8 vs int64: 8x)
"astype yaxlitlaydi" Kesiladi (1.9 → 1)
"a = a*2 = a *= 2" *= joyida (xotira kam)
"Har doim .copy()" View tez (kerakda copy)
"Optimallashtirish avval" Avval to'g'ri, keyin tez
"Taxmin bilan optimallashtir" O'lcha (timeit)
"float32 doim yetarli" Aniqlik kerak bo'lsa float64

6. Keng tarqalgan xatolar va yechimlari

1. Massivda Python sikl

python
for i in range(len(a)): b[i] = a[i]*2   # ⚠️ sekin
b = a * 2                                # ✅ vektorlangan

2. Keraksiz katta dtype

python
np.array(baholar)  # int64 (0-100 uchun)  # ⚠️ 8x xotira
np.array(baholar, dtype=np.int8)          # ✅

3. astype oraliq oshishi

python
np.array([300]).astype(np.int8)          # ⚠️ 300 > 127 (buziladi)
# oraliqni tekshir                         # ✅

4. Keraksiz nusxa (.copy())

python
b = a[1:100].copy()  # o'qish uchun       # ⚠️ keraksiz nusxa
b = a[1:100]         # view (tez)          # ✅

5. a = a * 2 katta massivda

python
a = a * 2   # katta massiv                # ⚠️ ikki barobar xotira
a *= 2      # joyida                       # ✅

6. O'lchamasdan optimallashtirish

python
# "bu sekin bo'lsa kerak"                  # ⚠️ taxmin
# timeit bilan o'lcha                       # ✅

7. float teng taqqoslash

python
a == 0.1     # ⚠️ float aniqlik (24.16)
np.isclose(a, 0.1)                          # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 24.1–24.3 (o'tilgan): NumPy asoslari
  • 24.12-dars: pandas unumdorlik — NumPy ustida
  • 29.1-dars: Unumdorlikni o'lchash — profiling
  • 29.2-dars: Profiling amaliyoti
  • 25-qism: ML — katta ma'lumot (dtype, tezlik)

8. Eng yaxshi amaliyotlar

  1. Sikl o'rniga vektorlashtir (eng katta ta'sir).

  2. To'g'ri dtype (xotira — kerakincha).

  3. astype ehtiyot (kesish, oraliq).

  4. Joyida amal (*=) katta massivda.

  5. Nusxani kamaytir (view, kerakda copy).

  6. O'lcha (timeit), taxmin qilma.

  7. Avval to'g'ri, keyin tez.

  8. float32 — aniqlik yetsa (xotira yarmi).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # Nega NumPy tez?
2.  # vektorlashtirish nima?
3.  # dtype nima?
4.  # int8 vs int64 xotira?
5.  # astype nima?
6.  # float→int astype?
7.  # joyida amal nima?
8.  # a*=2 vs a=a*2?
9.  # view nima beradi?
10. # nbytes nima?
11. # o'lchash nima?
12. # avval to'g'ri yoki tez?
Javoblar
  1. Uzluksiz xotira + bir tur + vektorlangan
  2. Sikl o'rniga massiv amali
  3. Element turi (va xotira hajmi)
  4. int8 — 1 bayt, int64 — 8 bayt (8x)
  5. Tur o'zgartirish (nusxa)
  6. Kasr kesiladi (1.9 → 1)
  7. Massivni o'zi ustida o'zgartirish
  8. *= joyida (xotira kam), a=a*2 yangi
  9. Nusxasiz (tez, xotira tejaydi)
  10. Jami bayt (xotira)
  11. Tezlikni aniq tekshirish (timeit)
  12. Avval to'g'ri, keyin tez

Vazifa 2: Xatolarni tuzating

python
1.  for i in range(len(a)): b[i]=a[i]*2   # vektorlangan

2.  np.array(baholar)  # 0-100 int64       # int8

3.  a = a * 2  # katta massiv               # a *= 2

4.  b = a[1:100].copy()  # o'qish           # view

5.  # taxmin bilan optimallashtir           # timeit
Javoblar
python
1.  b = a * 2

2.  np.array(baholar, dtype=np.int8)

3.  a *= 2

4.  b = a[1:100]

5.  timeit.timeit(...)

Vazifa 3: Vektorlashtirish

Solishtir:

  1. Python sikl
  2. Vektorlangan
  3. Natija teng
  4. Murakkab amal

Vazifa 4: dtype

Xotira:

  1. Turli dtype (itemsize)
  2. nbytes (jami)
  3. int8 vs int64
  4. Oraliq

Vazifa 5: astype va joyida

Amal:

  1. astype (float→int)
  2. Joyida (*=)
  3. View vs copy
  4. Xotira farqi

Vazifa 6: Katta ma'lumot

Samarali:

  1. To'g'ri dtype
  2. Vektorlangan
  3. Joyida amal
  4. Xotira taqqos

Vazifa 7: O'ylash

NumPy unumdorligi uch tamoyilga asoslanadi: vektorlashtirish (sikl o'rniga massiv amali), to'g'ri dtype (xotira), nusxasizlik (view). Bularning ortida umumiy g'oya bor: kompyuter apparatiga (protsessor, xotira) moslash. Nima uchun "apparatga mos kod tez" (mechanical sympathy), va bu "avval to'g'ri, keyin tez" (premature optimization) tamoyili bilan qanday muvozanatlashadi — ya'ni nega optimallashtirishni o'lchashdan boshlash kerak?

Javob

Qisqa javob: NumPy tez, chunki apparatga mos ishlaydi: uzluksiz xotira (protsessor keshi tez o'qiydi), bir tur (tekshirish yo'q), vektorlangan (C darajasi, protsessor SIMD). Bu "mexanik hamdardlik" (mechanical sympathy) — kompyuter qanday ishlashini tushunib, unga mos kod yozish (apparatga qarshi emas). Lekin muvozanat kerak: "avval to'g'ri, keyin tez" (premature optimization is the root of all evil — Knuth). Ya'ni: avval ishlaydigan, to'g'ri kod, keyin (agar sekin bo'lsa) o'lchab (timeit, profiling — 29.1) optimallashtir. Chunki: ko'pincha kod yetarli tez (optimallashtirish keraksiz — vaqt isrofi), va sekin joy kutilmagan bo'ladi (taxmin noto'g'ri). O'lchash — qayerni optimallashtirishni ko'rsatadi. "Mos kod tez, lekin avval o'lcha".

1. Mexanik hamdardlik (mechanical sympathy)

Kompyuter apparatini (protsessor, xotira, kesh) tushunib, unga mos kod: uzluksiz xotira (kesh), bir tur (tekshirish yo'q), vektorlangan (SIMD). Apparatga qarshi emas, mos.

2. NumPy qanday apparatga mos

Tamoyil Apparat
Uzluksiz xotira Protsessor keshi (tez)
Bir tur Tur tekshirish yo'q
Vektorlangan SIMD (bir amal, ko'p ma'lumot)

3. "Avval to'g'ri, keyin tez"

Knuth: "premature optimization is the root of all evil". Avval ishlaydigan kod (to'g'ri), keyin (kerak bo'lsa) tez. Chunki:

  • Ko'pincha yetarli tez (optimallashtirish keraksiz)
  • Sekin joy kutilmagan (taxmin xato)
  • Erta optimallashtirish — murakkablik, vaqt isrofi

4. Nega o'lchashdan boshlash

O'lchash (timeit, profiling — 29.1) qayerni optimallashtirishni ko'rsatadi (taxmin emas). "O'lcha, keyin tuzat" — 80% vaqt 20% kod'da (odatda). Bilmasdan optimallashtirish — noto'g'ri joyga kuch.

5. Muhandislik saboqlari

  1. Apparatga mos kod tez (mechanical sympathy)
  2. Lekin avval to'g'ri (premature optimization xavfi)
  3. O'lchab optimallashtir (taxmin emas)
  4. NumPy — apparatga mos, lekin o'ylab ishlat

6. Xulosa

  1. NumPy apparatga mos (uzluksiz, bir tur, vektorlangan)
  2. Mexanik hamdardlik — tez kod asosi
  3. Avval to'g'ri, keyin (o'lchab) tez
  4. Optimallashtirish — o'lchashdan boshlanadi

Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.


Xulosa

Bu darsda NumPy unumdorligini o'rgandik.

Eng muhim uch fikr:

  1. Nega NumPy tez va vektorlashtirish. NumPy tezligi uch tamoyil: uzluksiz xotira (C massivi — protsessor keshi tez o'qiydi), bir tur (dtype — har amalda tur tekshirish yo'q), amal C darajasida (vektorlangan, Python sikl emas). Vektorlashtirish — Python sikl (for) o'rniga butun massiv amali (a * 2 + 1): natija bir xil, lekin 10–100 barobar tez. Qoida: massivda sikl ko'rsangiz, vektorlashtirishga harakat qil — eng katta unumdorlik ta'siri.

  2. dtype, astype, joyida amal. dtype element turi va xotira hajmini belgilaydi: int8 (1 bayt) vs int64 (8 bayt) — 8 barobar farq (million element: 1MB vs 8MB). To'g'ri dtype tanla (kichik sonlarga int8/int16). .itemsize (element bayt), .nbytes (jami). astype(dtype) — tur o'zgartirish (yangi massiv; float → int kasrni kesadi). Joyida amal (a *= 2, a += 10) — massivni o'zi ustida (yangi massiv yo'q — xotira tejaydi); a = a * 2 esa yangi massiv. View 24.3-bob — nusxasiz (tez, xotira tejaydi).

  3. O'lchash va muvozanat. Unumdorlikni o'lchab tekshir (time.perf_counter, timeit, %timeit) — taxmin qilmasdan. "Avval to'g'ri, keyin tez" (premature optimization — Knuth): avval ishlaydigan kod, keyin (kerak bo'lsa, o'lchab) optimallashtir. NumPy unumdorligi apparatga mos ishlashga (mechanical sympathy — uzluksiz xotira, bir tur, vektorlangan) asoslanadi. Katta ma'lumotda bu farq soatlar vs soniyalar. Tamoyillar: vektorlashtir, to'g'ri dtype, nusxani kamaytir, o'lcha. Bu — ma'lumot muhandisligining asosi.

Keyingi darsda pandas: Series va DataFrame ni o'rganamiz: NumPy ustida qurilgan, belgilangan (nomlangan) ma'lumot tuzilmalari — jadval ma'lumoti bilan ishlashning asosiy vositasi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!