3-bo‘lim

NumPy - massivlar bilan ishlash

ndarray yaratish, indekslash, vektorlashtirilgan amallar, broadcasting va statistik funksiyalar.

🕑 23 daqiqa o‘qish 📄 615 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Nima uchun NumPy?
  2. Massiv yaratish
  3. Tasodifiy sonlar
  4. Massiv xossalari
  5. Indekslash va kesish
  6. Shartli tanlash
  7. Vektorlashtirilgan amallar
  8. Broadcasting
  9. Shaklni o'zgartirish
  10. Statistik funksiyalar
  11. O'q bo'yicha amallar
  12. Normalizatsiya - amaliy misol
  13. Foydali funksiyalar
  14. Xulosa

NumPy - Python dagi barcha ilmiy hisoblashlarning poydevori. Pandas, scikit-learn va TensorFlow - hammasi uning ustiga qurilgan.

Nima uchun NumPy? #

Python
import numpy as np
import time

# Oddiy Python ro'yxati
royxat = list(range(1_000_000))
boshlandi = time.perf_counter()
natija = [x * 2 for x in royxat]
print(f"Ro'yxat: {time.perf_counter() - boshlandi:.4f} soniya")

# NumPy massivi
massiv = np.arange(1_000_000)
boshlandi = time.perf_counter()
natija = massiv * 2
print(f"NumPy:   {time.perf_counter() - boshlandi:.4f} soniya")
Natija
Ro'yxat: 0.0682 soniya
NumPy:   0.0021 soniya

30 barobar tezroq.

Nima uchun bunchalik tez?
Python ro'yxatiNumPy massivi
XotiradaKo'rsatkichlar to'plamiUzluksiz blok
TurlarHar xil bo'lishi mumkinBir xil
AmallarPython tsikliC tilida bajariladi

NumPy ma'lumotni xotirada ketma-ket saqlaydi va amallarni kompilyatsiya qilingan C kodida bajaradi.

Massiv yaratish #

Python
import numpy as np

# Ro'yxatdan
sonlar = np.array([1, 2, 3, 4, 5])
print(sonlar)
Natija
[1 2 3 4 5]
Python
# Ikki o'lchovli
jadval = np.array([
    [65, 2, 620],
    [90, 3, 780],
    [120, 4, 1150],
])
print(jadval)
print("Shakl:", jadval.shape)
Natija
[[  65    2  620]
 [  90    3  780]
 [ 120    4 1150]]
Shakl: (3, 3)
Python
nollar    = np.zeros((2, 3))          # nollar bilan
birlar    = np.ones((3, 2))           # birlar bilan
toldirgan = np.full((2, 2), 7)        # ma'lum qiymat bilan
birlik    = np.eye(3)                 # birlik matritsa
oraliq    = np.arange(0, 10, 2)       # 0 dan 10 gacha, qadam 2
tekis     = np.linspace(0, 1, 5)      # 0 dan 1 gacha 5 ta nuqta

print(oraliq)
print(tekis)
Natija
[0 2 4 6 8]
[0.   0.25 0.5  0.75 1.  ]

Tasodifiy sonlar #

Python
np.random.seed(42)                        # takrorlanuvchanlik uchun

tasodifiy   = np.random.rand(3, 2)        # [0, 1) oralig'ida
normal      = np.random.randn(1000)       # normal taqsimot
butun       = np.random.randint(1, 100, 5)
tanlangan   = np.random.choice([10, 20, 30], size=4)

print(butun)
print(tanlangan)
Natija
[52 93 15 72 61]
[30 10 20 20]
seed ni har doim o'rnating

np.random.seed(42) bir xil "tasodifiy" sonlarni kafolatlaydi.

Bu tajribalarni takrorlash uchun juda muhim: siz va hamkasbingiz bir xil natija olasiz.

42 raqami - dasturchilar orasidagi an'ana, istalgan son bo'lishi mumkin.

Massiv xossalari #

Python
massiv = np.array([[1, 2, 3], [4, 5, 6]])

print("Shakl:      ", massiv.shape)      # (2, 3)
print("O'lchamlar: ", massiv.ndim)       # 2
print("Elementlar: ", massiv.size)       # 6
print("Turi:       ", massiv.dtype)      # int64
print("Bayt:       ", massiv.nbytes)     # 48
Python
# Turni o'zgartirish
kasr = massiv.astype(float)
print(kasr.dtype)
Natija
float64
Tur muhim
Python
butunlar = np.array([1, 2, 3])
butunlar[0] = 2.7
print(butunlar)
Natija
[2 2 3]

2.7 kesib tashlandi! Massiv turi int64 bo'lgani uchun.

Kasr kerak bo'lsa, avvaldan e'lon qiling:

Python
sonlar = np.array([1, 2, 3], dtype=float)

Indekslash va kesish #

Python
sonlar = np.array([10, 20, 30, 40, 50, 60])

print(sonlar[0])       # 10
print(sonlar[-1])      # 60
print(sonlar[1:4])     # [20 30 40]
print(sonlar[:3])      # [10 20 30]
print(sonlar[::2])     # [10 30 50]
print(sonlar[::-1])    # [60 50 40 30 20 10]
Python
jadval = np.array([
    [65,  2,  620],
    [90,  3,  780],
    [120, 4, 1150],
])

print(jadval[0, 2])      # 620 - birinchi qator, uchinchi ustun
print(jadval[1])         # [ 90   3 780] - butun qator
print(jadval[:, 0])      # [ 65  90 120] - birinchi ustun
print(jadval[:2, :2])    # birinchi ikki qator va ustun
Natija
620
[ 90   3 780]
[ 65  90 120]
[[65  2]
 [90  3]]
Kesish nusxa yaratmaydi
Python
asl = np.array([1, 2, 3, 4, 5])
qism = asl[1:4]
qism[0] = 999

print(asl)
Natija
[  1 999   3   4   5]

NumPy da kesish ko'rinish (view) qaytaradi, nusxa emas. Asl massiv ham o'zgardi!

Nusxa kerak bo'lsa:

Python
qism = asl[1:4].copy()

Shartli tanlash #

Bu ML da eng ko'p ishlatiladigan imkoniyat.

Python
narxlar = np.array([620, 780, 1150, 380, 950])

print(narxlar > 700)
print(narxlar[narxlar > 700])
Natija
[False  True  True False  True]
[ 780 1150  950]
Python
# Bir nechta shart
qimmat_emas = narxlar[(narxlar > 500) & (narxlar < 1000)]
print(qimmat_emas)

# Shartga ko'ra almashtirish
belgilangan = np.where(narxlar > 800, "qimmat", "arzon")
print(belgilangan)
Natija
[620 780 950]
['arzon' 'arzon' 'qimmat' 'arzon' 'qimmat']
and emas, &
Python
# XATO
narxlar[(narxlar > 500) and (narxlar < 1000)]   # ValueError

# TO'G'RI
narxlar[(narxlar > 500) & (narxlar < 1000)]

NumPy da mantiqiy amallar: & (va), | (yoki), ~ (emas). Qavslarni unutmang - ular majburiy.

Vektorlashtirilgan amallar #

Python
sonlar = np.array([1, 2, 3, 4])

print(sonlar + 10)      # [11 12 13 14]
print(sonlar * 2)       # [2 4 6 8]
print(sonlar ** 2)      # [ 1  4  9 16]
print(np.sqrt(sonlar))  # [1.   1.41 1.73 2.  ]
Python
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])

print(a + b)            # [11 22 33]
print(a * b)            # [10 40 90]
print(np.dot(a, b))     # 140 - skalyar ko'paytma
Tsikl yozmang
Python
# YOMON - sekin
natija = []
for son in sonlar:
    natija.append(son * 2 + 1)

# YAXSHI - tez va qisqa
natija = sonlar * 2 + 1

NumPy bilan ishlaganda tsikl yozayotgan bo'lsangiz - deyarli har doim uni vektorlashtirilgan amal bilan almashtirish mumkin.

Broadcasting #

Turli shakldagi massivlar ustida amal bajarish.

Kichik massiv katta massivga "cho'ziladi" Matritsa (3×3) 1 2 3 4 5 6 7 8 9 + Vektor (3,) 10 20 30 har bir qatorga takrorlanadi = Natija (3×3) 11 22 33 14 25 36 17 28 39 Xotirada nusxa yaratilmaydi - NumPy buni samarali bajaradi
Broadcasting kod yozishni ancha soddalashtiradi
Python
matritsa = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
vektor = np.array([10, 20, 30])

print(matritsa + vektor)
Natija
[[11 22 33]
 [14 25 36]
 [17 28 39]]
Broadcasting qoidalari

Ikki massiv mos kelishi uchun, o'ngdan chapga qarab har bir o'lcham:

  1. teng bo'lishi, yoki
  2. biri 1 ga teng bo'lishi kerak
Natija
(3, 3)  va  (3,)      →  mos     (3,) ni (1, 3) deb qaraladi
(3, 3)  va  (3, 1)    →  mos     ustun sifatida cho'ziladi
(3, 3)  va  (2,)      →  mos emas

Shaklni o'zgartirish #

Python
sonlar = np.arange(12)
print(sonlar.reshape(3, 4))
print(sonlar.reshape(4, -1))    # -1: qolganini o'zi hisoblasin
Natija
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
Python
matritsa = np.array([[1, 2], [3, 4]])

print(matritsa.T)             # transpozitsiya
print(matritsa.flatten())     # bir o'lchovga
print(matritsa.ravel())       # bir o'lchovga (ko'rinish)
reshape(-1, 1) - ML da eng ko'p uchraydigan

scikit-learn X uchun ikki o'lchovli massivni kutadi:

Python
maydon = np.array([65, 90, 120])        # shakl: (3,)
X = maydon.reshape(-1, 1)               # shakl: (3, 1)

"Expected 2D array, got 1D array instead" xatosini ko'rsangiz - javob shu.

Statistik funksiyalar #

Python
narxlar = np.array([620, 780, 1150, 380, 950, 700])

print("Yig'indi:      ", narxlar.sum())
print("O'rtacha:      ", narxlar.mean())
print("Mediana:       ", np.median(narxlar))
print("Standart og'ish:", narxlar.std().round(2))
print("Eng kichik:    ", narxlar.min())
print("Eng katta:     ", narxlar.max())
print("Eng katta indeks:", narxlar.argmax())
Natija
Yig'indi:       4580
O'rtacha:       763.33
Mediana:        740.0
Standart og'ish: 246.42
Eng kichik:     380
Eng katta:      1150
Eng katta indeks: 2

O'q bo'yicha amallar #

Python
jadval = np.array([
    [65,  2,  620],
    [90,  3,  780],
    [120, 4, 1150],
])

print("Ustunlar bo'yicha:", jadval.mean(axis=0))
print("Qatorlar bo'yicha:", jadval.mean(axis=1))
Natija
Ustunlar bo'yicha: [ 91.67   3.   850.  ]
Qatorlar bo'yicha: [229.  291.  424.67]
axis ni eslab qolish
  • axis=0 - qatorlar bo'ylab pastga harakat, natija har bir ustun uchun
  • axis=1 - ustunlar bo'ylab o'ngga harakat, natija har bir qator uchun

Oddiy qoida: axis - yo'q qilinadigan o'lcham. (3, 3) massivda axis=0 bo'lsa, natija (3,) bo'ladi.

Normalizatsiya - amaliy misol #

ML da ma'lumotni bir xil masshtabga keltirish juda muhim:

Python
belgilar = np.array([
    [65,  2, 620],
    [90,  3, 780],
    [120, 4, 1150],
    [45,  1, 380],
])

# Min-max normalizatsiya: [0, 1] oralig'iga
eng_kichik = belgilar.min(axis=0)
eng_katta  = belgilar.max(axis=0)
normal = (belgilar - eng_kichik) / (eng_katta - eng_kichik)

print(normal.round(2))
Natija
[[0.27 0.33 0.31]
 [0.6  0.67 0.52]
 [1.   1.   1.  ]
 [0.   0.   0.  ]]
Python
# Standartlashtirish: o'rtacha 0, standart og'ish 1
standart = (belgilar - belgilar.mean(axis=0)) / belgilar.std(axis=0)
print(standart.round(2))
Natija
[[-0.35 -0.45 -0.5 ]
 [ 0.53  0.45 -0.05]
 [ 1.59  1.34  1.02]
 [-1.77 -1.34 -1.46]]
Nima uchun bu kerak?

maydon 40-150 oralig'ida, xonalar 1-4 oralig'ida. Ko'p algoritmlar uchun bu muammo: katta sonli ustun natijaga nomutanosib ta'sir qiladi.

6-bo'limda buni scikit-learn vositalari bilan bajarishni ko'ramiz.

Foydali funksiyalar #

Python
a = np.array([3, 1, 4, 1, 5, 9, 2, 6])

print(np.sort(a))              # [1 1 2 3 4 5 6 9]
print(np.argsort(a))           # tartiblangan indekslar
print(np.unique(a))            # takrorlanmagan qiymatlar
print(np.cumsum(a))            # jamlanuvchi yig'indi

b = np.array([1, 2, np.nan, 4])
print(np.isnan(b))             # [False False  True False]
print(np.nanmean(b))           # 2.33 - NaN e'tiborsiz
Python
# Birlashtirish
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6]])

print(np.vstack([x, y]))       # vertikal
print(np.hstack([x, x]))       # gorizontal
Amaliy topshiriq
  1. 1 dan 20 gacha sonlardan massiv yarating va faqat juftlarini chiqaring.
  2. (4, 5) shaklidagi tasodifiy massiv yarating (seed=42).
  3. Uning har bir ustuni uchun o'rtacha va standart og'ishni hisoblang.
  4. 100 dan katta elementlarni topib, ularni 100 ga almashtiring.
  5. reshape bilan (20,) massivni (4, 5) va (5, 4) ga aylantiring.
  6. Ikki massivning skalyar ko'paytmasini np.dot bilan hisoblang.
  7. Broadcasting bilan matritsaning har bir ustunidan uning o'rtachasini ayiring.
  8. Min-max normalizatsiya funksiyasini yozing.
  9. np.where bilan sonlarni "musbat"/"manfiy" deb belgilang.
  10. Tsikl va vektorlashtirilgan amalning tezligini o'lchab solishtiring.

Xulosa #

  • NumPy massivlari Python ro'yxatlaridan o'nlab barobar tezroq.
  • np.array, zeros, ones, arange, linspace - massiv yaratish usullari.
  • np.random.seed() natijalarni takrorlanuvchi qiladi.
  • Kesish nusxa emas, ko'rinish qaytaradi - .copy() ni unutmang.
  • Shartli tanlashda &, |, ~ ishlatiladi, qavslar majburiy.
  • Vektorlashtirilgan amallar tsiklni almashtiradi - tsikl yozmang.
  • Broadcasting turli shakldagi massivlarni birlashtiradi.
  • reshape(-1, 1) - scikit-learn uchun eng ko'p kerak bo'ladi.
  • axis=0 ustunlar bo'yicha, axis=1 qatorlar bo'yicha hisoblaydi.

Keyingi bo'limda Pandas bilan jadvallarni o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.