4-bo‘lim
Pandas - jadvallar bilan ishlash
DataFrame va Series, fayl o'qish, filtrlash, guruhlash, birlashtirish va tezkor ma'lumot tahlili.
Ushbu bo‘lim mundarijasi
Amaliy mashinali o'qitishning katta qismi - jadval ko'rinishidagi ma'lumot bilan ishlash. Pandas aynan shu uchun yaratilgan.
Ikki asosiy tuzilma #
| Tuzilma | Nima |
|---|---|
| Series | Bir o'lchovli - bitta ustun |
| DataFrame | Ikki o'lchovli - butun jadval |
import pandas as pd
import numpy as np
narxlar = pd.Series([620, 780, 1150, 380], name="narx")
print(narxlar)
0 620
1 780
2 1150
3 380
Name: narx, dtype: int64
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)
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 #
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)
# 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"],
)
O'zbekcha matnli fayllarda tez-tez uchraydi:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf3
Yechim - kodlashni ko'rsatish:
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:
print(uylar.head(3)) # birinchi 3 qator
print(uylar.tail(3)) # oxirgi 3 qator
print(uylar.shape) # (qatorlar, ustunlar)
print(uylar.columns) # ustun nomlari
uylar.info()
<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
print(uylar.describe())
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 buyruqinfo() 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 #
print(uylar["narx"]) # Series
print(uylar[["maydon", "narx"]]) # DataFrame
# Nuqta bilan (faqat oddiy nomlar uchun)
print(uylar.narx)
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:
X = uylar[["maydon", "xonalar"]]
y = uylar["narx"]
Qatorlarni tanlash #
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"]])
| Usul | Nima bo'yicha |
|---|---|
iloc | Pozitsiya (0, 1, 2...) |
loc | Nom/indeks (label) |
loc chegarani o'z ichiga oladiuylar.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 #
qimmat = uylar[uylar["narx"] > 700]
print(qimmat)
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
# 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 #
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"]])
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
# 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# 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 #
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.
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())
tuman
Chilonzor 740.0
Sergeli 415.0
Yunusobod 900.0
Name: narx, dtype: float64
# Bir nechta funksiya
print(savdo.groupby("tuman")["narx"].agg(["count", "mean", "min", "max"]))
count mean min max
tuman
Chilonzor 2 740.0 700 780
Sergeli 2 415.0 380 450
Yunusobod 1 900.0 900 900
# Har bir ustun uchun boshqa funksiya
print(savdo.groupby("tuman").agg(
uylar_soni=("narx", "count"),
ortacha_narx=("narx", "mean"),
ortacha_xona=("xonalar", "mean"),
))
Jamlovchi jadval #
print(savdo.pivot_table(
values="narx",
index="tuman",
columns="xonalar",
aggfunc="mean",
))
xonalar 1 2 3
tuman
Chilonzor NaN 700.0 780.0
Sergeli 380.0 450.0 NaN
Yunusobod NaN NaN 900.0
# Chastota jadvali
print(pd.crosstab(uylar["tuman"], uylar["toifa"]))
Bo'sh qiymatlar #
malumot = pd.DataFrame({
"maydon": [65, 90, np.nan, 45],
"narx": [620, np.nan, 1150, 380],
})
print(malumot.isna().sum())
maydon 1
narx 1
dtype: int64
# 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
Har bir ustun uchun alohida qaror kerak:
| Vaziyat | Yechim |
|---|---|
| Bo'shlar 5% dan kam | Qatorlarni o'chirish |
| Ustunning 60%+ bo'sh | Ustunni o'chirish |
| Sonli, simmetrik taqsimot | O'rtacha bilan to'ldirish |
| Sonli, chetdagi qiymatlar bor | Mediana bilan |
| Toifali | Eng ko'p uchraydigan qiymat |
| Bo'shligining o'zi ma'noli | Yangi "bo'sh" toifasi |
6-bo'limda buni batafsil ko'ramiz.
Takrorlanuvchi qatorlar #
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 #
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)
id maydon tuman_id tuman_nomi
0 1 65 1 Chilonzor
1 2 90 2 Sergeli
2 3 120 1 Chilonzor
how | Nima qoladi |
|---|---|
inner | Faqat ikkalasida ham bor qatorlar |
left | Chapdagi hamma qator |
right | O'ngdagi hamma qator |
outer | Ikkalasidan hammasi |
# Ustma-ust qo'yish
hammasi = pd.concat([jadval1, jadval2], ignore_index=True)
# Yonma-yon
kengaytirilgan = pd.concat([jadval1, jadval2], axis=1)
Toifali ma'lumot #
print(uylar["tuman"].value_counts())
print(uylar["tuman"].nunique())
print(uylar["tuman"].unique())
# One-hot kodlash - ML uchun kerak
kodlangan = pd.get_dummies(uylar, columns=["tuman"], drop_first=True)
print(kodlangan.columns.tolist())
['maydon', 'xonalar', 'yosh', 'narx', 'tuman_Mirzo Ulug'bek',
'tuman_Sergeli', 'tuman_Yakkasaroy', 'tuman_Yunusobod']
Korrelyatsiya #
sonli = uylar[["maydon", "xonalar", "yosh", "narx"]]
print(sonli.corr().round(2))
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
| Qiymat | Ma'nosi |
|---|---|
+1.0 | Mukammal to'g'ri bog'liqlik |
+0.7 ... +0.9 | Kuchli to'g'ri |
0 | Bog'liqlik yo'q |
-0.7 ... -0.9 | Kuchli teskari |
narx bilan maydon orasida 0.99 - maydon narxni deyarli to'liq
tushuntiradi.
Muhim: korrelyatsiya sababiy bog'liqlikni anglatmaydi.
Saqlash #
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 unutmangAks holda saqlangan faylda keraksiz birinchi ustun paydo bo'ladi va har safar o'qiganda yangisi qo'shilaveradi:
Unnamed: 0,maydon,narx
0,65,620
- 20 qatorli uylar jadvalini yarating (maydon, xonalar, tuman, yosh, narx).
head(),info(),describe()bilan ko'rib chiqing.- Narxi o'rtachadan yuqori uylarni filtrlang.
narx_m2ustunini qo'shing.- Tuman bo'yicha guruhlab, o'rtacha narx va uylar sonini chiqaring.
pd.cutbilan uylarni uch narx toifasiga bo'ling.- Ataylab bir necha
NaNqo'ying va ularni mediana bilan to'ldiring. tumanustuniniget_dummiesbilan kodlang.- Korrelyatsiya matritsasini hisoblang va eng kuchli bog'liqlikni toping.
- Natijani CSV ga saqlang va qayta o'qib tekshiring.
Xulosa #
- Series - bitta ustun, DataFrame - butun jadval.
- Yangi ma'lumotni
head(),info(),describe()bilan boshlang. ilocpozitsiya bo'yicha,locnom bo'yicha ishlaydi.- Filtrlashda
&,|va qavslar ishlatiladi. groupby- ajrat, qo'lla, birlashtir; SQL dagiGROUP BYbilan bir xil.isna().sum()bo'sh qiymatlarni sanaydi.- Bo'shlarni to'ldirishda mediana o'rtachadan ko'ra ishonchliroq.
mergejadvallarni birlashtiradi (howparametri muhim).get_dummiestoifali ustunni ML uchun raqamga aylantiradi.corr()belgilar orasidagi bog'liqlikni ko'rsatadi.- Saqlashda
index=Falseni unutmang.
Keyingi bo'limda ma'lumotni vizuallashtirishni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.