4-bo‘lim

Pandas - jadvallar bilan ishlash

DataFrame va Series, fayl o'qish, filtrlash, guruhlash, birlashtirish va tezkor ma'lumot tahlili.

🕑 24 daqiqa o‘qish 📄 654 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Ikki asosiy tuzilma
  2. Fayldan o'qish
  3. Birinchi ko'rik
  4. Ustunlarni tanlash
  5. Qatorlarni tanlash
  6. Filtrlash
  7. Yangi ustun qo'shish
  8. Saralash
  9. Guruhlash
  10. Jamlovchi jadval
  11. Bo'sh qiymatlar
  12. Takrorlanuvchi qatorlar
  13. Jadvallarni birlashtirish
  14. Toifali ma'lumot
  15. Korrelyatsiya
  16. Saqlash
  17. Xulosa

Amaliy mashinali o'qitishning katta qismi - jadval ko'rinishidagi ma'lumot bilan ishlash. Pandas aynan shu uchun yaratilgan.

Ikki asosiy tuzilma #

TuzilmaNima
SeriesBir o'lchovli - bitta ustun
DataFrameIkki o'lchovli - butun jadval
Python
import pandas as pd
import numpy as np

narxlar = pd.Series([620, 780, 1150, 380], name="narx")
print(narxlar)
Natija
0     620
1     780
2    1150
3     380
Name: narx, dtype: int64
Python
uylar = pd.DataFrame({
    "maydon":  [65, 90, 120, 45, 78],
    "xonalar": [2, 3, 4, 1, 3],
    "tuman":   ["Yunusobod", "Chilonzor", "Mirzo Ulug'bek", "Sergeli", "Yakkasaroy"],
    "yosh":    [12, 5, 2, 25, 8],
    "narx":    [620, 780, 1150, 380, 810],
})

print(uylar)
Natija
   maydon  xonalar           tuman  yosh  narx
0      65        2       Yunusobod    12   620
1      90        3       Chilonzor     5   780
2     120        4  Mirzo Ulug'bek     2  1150
3      45        1         Sergeli    25   380
4      78        3      Yakkasaroy     8   810

Fayldan o'qish #

Python
uylar = pd.read_csv("malumotlar/xom/uylar.csv")

# Boshqa formatlar
pd.read_excel("hisobot.xlsx", sheet_name="Savdo")
pd.read_json("malumot.json")
pd.read_sql("SELECT * FROM mahsulotlar", ulanish)
Python
# Foydali parametrlar
uylar = pd.read_csv(
    "uylar.csv",
    sep=";",                       # ajratuvchi
    encoding="utf-8",
    decimal=",",                   # kasr belgisi
    na_values=["", "yo'q", "-"],   # bo'sh deb hisoblanadigan qiymatlar
    parse_dates=["sotilgan_sana"],
)
Kodlash muammosi

O'zbekcha matnli fayllarda tez-tez uchraydi:

Natija
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf3

Yechim - kodlashni ko'rsatish:

Python
pd.read_csv("uylar.csv", encoding="cp1251")
pd.read_csv("uylar.csv", encoding="latin1")

Excel dan eksport qilingan fayllarda ko'pincha cp1251 bo'ladi.

Birinchi ko'rik #

Yangi ma'lumotni olganda har doim shu buyruqlarni bajaring:

Python
print(uylar.head(3))       # birinchi 3 qator
print(uylar.tail(3))       # oxirgi 3 qator
print(uylar.shape)         # (qatorlar, ustunlar)
print(uylar.columns)       # ustun nomlari
Python
uylar.info()
Natija
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 5 columns):
 #   Column   Non-Null Count  Dtype
---  ------   --------------  -----
 0   maydon   5 non-null      int64
 1   xonalar  5 non-null      int64
 2   tuman    5 non-null      object
 3   yosh     5 non-null      int64
 4   narx     5 non-null      int64
dtypes: int64(4), object(1)
memory usage: 328.0 bytes
Python
print(uylar.describe())
Natija
           maydon   xonalar       yosh         narx
count    5.000000  5.000000   5.000000     5.000000
mean    79.600000  2.600000  10.400000   748.000000
std     28.457864  1.140175   8.961027   282.276107
min     45.000000  1.000000   2.000000   380.000000
25%     65.000000  2.000000   5.000000   620.000000
50%     78.000000  3.000000   8.000000   780.000000
75%     90.000000  3.000000  12.000000   810.000000
max    120.000000  4.000000  25.000000  1150.000000
info() va describe() - birinchi ikki buyruq

info() sizga aytadi:

  • Nechta qator va ustun bor
  • Qaysi ustunda bo'sh qiymatlar bor
  • Har bir ustun turi to'g'rimi

describe() esa:

  • Qiymatlar oralig'i mantiqiymi (yosh -5 bo'lmasin)
  • Chetdagi qiymatlar (outliers) bormi
  • Taqsimot qanday

Bu ikki buyruq muammolarning yarmini darhol ko'rsatadi.

Ustunlarni tanlash #

Python
print(uylar["narx"])                       # Series
print(uylar[["maydon", "narx"]])           # DataFrame

# Nuqta bilan (faqat oddiy nomlar uchun)
print(uylar.narx)
Bir va ikki qavs farqi
Python
uylar["narx"]        # Series - bir o'lchovli
uylar[["narx"]]      # DataFrame - ikki o'lchovli

scikit-learn ko'pincha DataFrame ni kutadi - shuning uchun X uchun ikki qavs ishlatiladi:

Python
X = uylar[["maydon", "xonalar"]]
y = uylar["narx"]

Qatorlarni tanlash #

Python
print(uylar.iloc[0])          # pozitsiya bo'yicha
print(uylar.iloc[1:3])        # 1 va 2-qator
print(uylar.iloc[0, 2])       # birinchi qator, uchinchi ustun

print(uylar.loc[0])           # indeks bo'yicha
print(uylar.loc[0, "narx"])   # indeks va ustun nomi
print(uylar.loc[0:2, ["maydon", "narx"]])
UsulNima bo'yicha
ilocPozitsiya (0, 1, 2...)
locNom/indeks (label)
loc chegarani o'z ichiga oladi
Python
uylar.iloc[0:3]   # 0, 1, 2 - uchta qator
uylar.loc[0:3]    # 0, 1, 2, 3 - to'rtta qator!

Bu Python odatiga zid, lekin loc nomlar bilan ishlagani uchun shunday.

Filtrlash #

Python
qimmat = uylar[uylar["narx"] > 700]
print(qimmat)
Natija
   maydon  xonalar           tuman  yosh  narx
1      90        3       Chilonzor     5   780
2     120        4  Mirzo Ulug'bek     2  1150
4      78        3      Yakkasaroy     8   810
Python
# Bir nechta shart
tanlangan = uylar[(uylar["narx"] > 500) & (uylar["xonalar"] >= 3)]

# Ro'yxatdan
markaz = uylar[uylar["tuman"].isin(["Chilonzor", "Yakkasaroy"])]

# Matn bo'yicha
qidiruv = uylar[uylar["tuman"].str.contains("obod")]

# Oraliqda
orta = uylar[uylar["maydon"].between(60, 100)]

# query bilan - o'qishga qulay
natija = uylar.query("narx > 700 and xonalar >= 3")

Yangi ustun qo'shish #

Python
uylar["narx_m2"] = (uylar["narx"] / uylar["maydon"]).round(2)

uylar["katta"] = uylar["maydon"] > 80

uylar["toifa"] = pd.cut(
    uylar["narx"],
    bins=[0, 500, 800, 2000],
    labels=["arzon", "o'rtacha", "qimmat"],
)

print(uylar[["maydon", "narx", "narx_m2", "toifa"]])
Natija
   maydon  narx  narx_m2     toifa
0      65   620     9.54  o'rtacha
1      90   780     8.67  o'rtacha
2     120  1150     9.58    qimmat
3      45   380     8.44     arzon
4      78   810    10.38    qimmat
Python
# Funksiya qo'llash
uylar["yosh_toifa"] = uylar["yosh"].apply(
    lambda yosh: "yangi" if yosh < 5 else ("o'rta" if yosh < 15 else "eski")
)
apply sekin - imkon bo'lsa vektorlashtiring
Python
# Sekin
uylar["narx_m2"] = uylar.apply(lambda q: q["narx"] / q["maydon"], axis=1)

# Tez
uylar["narx_m2"] = uylar["narx"] / uylar["maydon"]

Katta jadvalda farq yuz barobargacha bo'lishi mumkin.

Saralash #

Python
print(uylar.sort_values("narx", ascending=False))

# Bir nechta ustun bo'yicha
print(uylar.sort_values(["tuman", "narx"], ascending=[True, False]))

# Eng qimmat 3 ta
print(uylar.nlargest(3, "narx"))
print(uylar.nsmallest(2, "narx"))

Guruhlash #

Bu Pandas ning eng kuchli imkoniyati.

Python
savdo = pd.DataFrame({
    "tuman":  ["Chilonzor", "Chilonzor", "Sergeli", "Sergeli", "Yunusobod"],
    "xonalar": [2, 3, 2, 1, 3],
    "narx":   [700, 780, 450, 380, 900],
})

print(savdo.groupby("tuman")["narx"].mean())
Natija
tuman
Chilonzor    740.0
Sergeli      415.0
Yunusobod    900.0
Name: narx, dtype: float64
Python
# Bir nechta funksiya
print(savdo.groupby("tuman")["narx"].agg(["count", "mean", "min", "max"]))
Natija
           count   mean  min  max
tuman
Chilonzor      2  740.0  700  780
Sergeli        2  415.0  380  450
Yunusobod      1  900.0  900  900
Python
# Har bir ustun uchun boshqa funksiya
print(savdo.groupby("tuman").agg(
    uylar_soni=("narx", "count"),
    ortacha_narx=("narx", "mean"),
    ortacha_xona=("xonalar", "mean"),
))
Ajratish → Qo'llash → Birlashtirish Asl jadval Chilonzor 700 Chilonzor 780 Sergeli 450 Sergeli 380 Yunusobod 900 Guruhlar 700780 450380 900 mean() 740 415 900 Natija Chilonzor 740 Sergeli 415 Yunusobod 900 SQL dagi GROUP BY bilan bir xil g'oya
groupby - ajrat, qo'lla, birlashtir

Jamlovchi jadval #

Python
print(savdo.pivot_table(
    values="narx",
    index="tuman",
    columns="xonalar",
    aggfunc="mean",
))
Natija
xonalar        1      2      3
tuman
Chilonzor    NaN  700.0  780.0
Sergeli    380.0  450.0    NaN
Yunusobod    NaN    NaN  900.0
Python
# Chastota jadvali
print(pd.crosstab(uylar["tuman"], uylar["toifa"]))

Bo'sh qiymatlar #

Python
malumot = pd.DataFrame({
    "maydon": [65, 90, np.nan, 45],
    "narx":   [620, np.nan, 1150, 380],
})

print(malumot.isna().sum())
Natija
maydon    1
narx      1
dtype: int64
Python
# Foizda
print((malumot.isna().sum() / len(malumot) * 100).round(1))

# O'chirish
malumot.dropna()                       # bo'sh qiymatli qatorlarni
malumot.dropna(subset=["narx"])        # faqat narx bo'sh bo'lsa
malumot.dropna(axis=1)                 # ustunni

# To'ldirish
malumot["maydon"].fillna(malumot["maydon"].mean())
malumot["narx"].fillna(malumot["narx"].median())
malumot.ffill()                        # oldingi qiymat bilan
Bo'sh qiymatlarni o'ylab to'ldiring

Har bir ustun uchun alohida qaror kerak:

VaziyatYechim
Bo'shlar 5% dan kamQatorlarni o'chirish
Ustunning 60%+ bo'shUstunni o'chirish
Sonli, simmetrik taqsimotO'rtacha bilan to'ldirish
Sonli, chetdagi qiymatlar borMediana bilan
ToifaliEng ko'p uchraydigan qiymat
Bo'shligining o'zi ma'noliYangi "bo'sh" toifasi

6-bo'limda buni batafsil ko'ramiz.

Takrorlanuvchi qatorlar #

Python
print(uylar.duplicated().sum())
uylar = uylar.drop_duplicates()

# Faqat ma'lum ustunlar bo'yicha
uylar = uylar.drop_duplicates(subset=["maydon", "tuman"], keep="first")

Jadvallarni birlashtirish #

Python
uylar = pd.DataFrame({
    "id": [1, 2, 3],
    "maydon": [65, 90, 120],
    "tuman_id": [1, 2, 1],
})

tumanlar = pd.DataFrame({
    "tuman_id": [1, 2],
    "tuman_nomi": ["Chilonzor", "Sergeli"],
})

birlashgan = uylar.merge(tumanlar, on="tuman_id", how="left")
print(birlashgan)
Natija
   id  maydon  tuman_id tuman_nomi
0   1      65         1  Chilonzor
1   2      90         2    Sergeli
2   3     120         1  Chilonzor
howNima qoladi
innerFaqat ikkalasida ham bor qatorlar
leftChapdagi hamma qator
rightO'ngdagi hamma qator
outerIkkalasidan hammasi
Python
# Ustma-ust qo'yish
hammasi = pd.concat([jadval1, jadval2], ignore_index=True)

# Yonma-yon
kengaytirilgan = pd.concat([jadval1, jadval2], axis=1)

Toifali ma'lumot #

Python
print(uylar["tuman"].value_counts())
print(uylar["tuman"].nunique())
print(uylar["tuman"].unique())
Python
# One-hot kodlash - ML uchun kerak
kodlangan = pd.get_dummies(uylar, columns=["tuman"], drop_first=True)
print(kodlangan.columns.tolist())
Natija
['maydon', 'xonalar', 'yosh', 'narx', 'tuman_Mirzo Ulug'bek',
 'tuman_Sergeli', 'tuman_Yakkasaroy', 'tuman_Yunusobod']

Korrelyatsiya #

Python
sonli = uylar[["maydon", "xonalar", "yosh", "narx"]]
print(sonli.corr().round(2))
Natija
         maydon  xonalar  yosh  narx
maydon     1.00     0.96 -0.85  0.99
xonalar    0.96     1.00 -0.78  0.95
yosh      -0.85    -0.78  1.00 -0.87
narx       0.99     0.95 -0.87  1.00
Korrelyatsiyani o'qish
QiymatMa'nosi
+1.0Mukammal to'g'ri bog'liqlik
+0.7 ... +0.9Kuchli to'g'ri
0Bog'liqlik yo'q
-0.7 ... -0.9Kuchli teskari

narx bilan maydon orasida 0.99 - maydon narxni deyarli to'liq tushuntiradi.

Muhim: korrelyatsiya sababiy bog'liqlikni anglatmaydi.

Saqlash #

Python
uylar.to_csv("malumotlar/tayyor/uylar.csv", index=False, encoding="utf-8")
uylar.to_excel("hisobot.xlsx", index=False, sheet_name="Uylar")
uylar.to_parquet("uylar.parquet")     # tez va ixcham
index=False ni unutmang

Aks holda saqlangan faylda keraksiz birinchi ustun paydo bo'ladi va har safar o'qiganda yangisi qo'shilaveradi:

Natija
Unnamed: 0,maydon,narx
0,65,620
Amaliy topshiriq
  1. 20 qatorli uylar jadvalini yarating (maydon, xonalar, tuman, yosh, narx).
  2. head(), info(), describe() bilan ko'rib chiqing.
  3. Narxi o'rtachadan yuqori uylarni filtrlang.
  4. narx_m2 ustunini qo'shing.
  5. Tuman bo'yicha guruhlab, o'rtacha narx va uylar sonini chiqaring.
  6. pd.cut bilan uylarni uch narx toifasiga bo'ling.
  7. Ataylab bir necha NaN qo'ying va ularni mediana bilan to'ldiring.
  8. tuman ustunini get_dummies bilan kodlang.
  9. Korrelyatsiya matritsasini hisoblang va eng kuchli bog'liqlikni toping.
  10. Natijani CSV ga saqlang va qayta o'qib tekshiring.

Xulosa #

  • Series - bitta ustun, DataFrame - butun jadval.
  • Yangi ma'lumotni head(), info(), describe() bilan boshlang.
  • iloc pozitsiya bo'yicha, loc nom bo'yicha ishlaydi.
  • Filtrlashda &, | va qavslar ishlatiladi.
  • groupby - ajrat, qo'lla, birlashtir; SQL dagi GROUP BY bilan bir xil.
  • isna().sum() bo'sh qiymatlarni sanaydi.
  • Bo'shlarni to'ldirishda mediana o'rtachadan ko'ra ishonchliroq.
  • merge jadvallarni birlashtiradi (how parametri muhim).
  • get_dummies toifali ustunni ML uchun raqamga aylantiradi.
  • corr() belgilar orasidagi bog'liqlikni ko'rsatadi.
  • Saqlashda index=False ni unutmang.

Keyingi bo'limda ma'lumotni vizuallashtirishni 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.