Asosiy qismga o'tish

Tanlash: loc, iloc va filtrlar

11-bob 10 kod bloki 1410 so'z

Bu bobdagi kod shu fayllar bilan ishlaydio'z kompyuteringizda ishga tushiring

Sahna: "menga faqat ..."

Tahlilchiga keladigan savollarning aksariyati "faqat" so'zi bilan boshlanadi: faqat Toshkentdagi e'lonlar, faqat avtomat uzatmali, faqat 2020 dan yangi, faqat model va yil ustunlari. Bu bob — jadvaldan kerakli qator va ustunlarni olishning hamma usullari.

python5 qator
import pandas as pd

avto = pd.read_csv(DATA / "avto_savdo.csv", parse_dates=["sana"], date_format="%d.%m.%Y")
avto = avto.set_index("elon_id")
avto.head(3)
elon_idsanamodelrangyilprobeg_kmuzatmaviloyatnarx
10012025-07-12 00:00:00CAPTIVAQora2013NaNAvtomatToshkent123 500 000 so'm
10022025-01-15 00:00:00NEXIA 3Qizil2012233862AvtomatToshkent32500000
10032025-07-01 00:00:00SPARKOq202431254MexanikaNamangan93 000 000 so'm

set_index("elon_id") — e'lon raqamini qator yorlig'i qildik. Endi har qatorning ma'noli nomi bor: 1001, 1002...

loc va iloc

loc yorliq bo'yicha (oxiri kiradi), iloc o'rin bo'yicha (oxiri kirmaydi)

loc yorliq bo'yicha (oxiri kiradi), iloc o'rin bo'yicha (oxiri kirmaydi)

Ikki usul, ikki xil savol:

  • loc — "yorlig'i shu bo'lgan qator va ustun": avto.loc[1005, "yil"].
  • iloc — "o'rni shu bo'lgan qator va ustun" (integer location): avto.iloc[4, 3] — 5-qator, 4-ustun.
python2 qator
print(avto.loc[1005, "model"], "|", avto.iloc[4, 1])
avto.loc[1003:1005, "model":"yil"]
Chiqish
Onix  | Onix
elon_idmodelrangyil
1003SPARKOq2024
1004SparkQizil2015
1005Onix Qizil2021

loc da kesish oxirini ham oladi: 1003:1005 — uchta qator, "model":"yil" — model dan yil gacha hamma ustunlar. Yorliqlar bilan "oxirgisidan bittasi oldin" degan tushuncha ma'nosiz — yorliq raqam emas bo'lishi mumkin.

matn1 qator
avto.iloc[2:5, [1, 4]]
elon_idmodelprobeg_km
1003SPARK31254
1004Spark201 112
1005Onix 86520

iloc — xuddi NumPy (3-bob): oxiri kirmaydi, ro'yxat bilan tanlash mumkin.

Qachon qaysi biri? Deyarli har doim loc: kod ustun nomi bilan yozilsa, ustunlar tartibi o'zgarganda ham to'g'ri ishlaydi. iloc — "birinchi 10 qator", "oxirgi ustun" kabi o'rin muhim bo'lgan joyda.

Shart bilan filtr

3-bobdagi mask pandas da ham ishlaydi:

python4 qator
toshkent = avto["viloyat"] == "Toshkent"
print(toshkent.sum(), "ta Toshkent e'loni")
yangi_avtomat = (avto["yil"] >= 2020) & (avto["uzatma"] == "Avtomat")
avto.loc[yangi_avtomat & toshkent, ["model", "yil", "narx"]].head()
Chiqish
71 ta Toshkent e'loni
elon_idmodelyilnarx
1128Captiva2020280500000
1129Spark202269 000 000 so'm
1370CAPTIVA2022337500000
1206Captiva2024408000000
1216Onix2024209500000

loc[shart, ustunlar] — qatorlarni shart bilan, ustunlarni nom bilan bitta qadamda. Shartlar — & (va), | (yoki), ~ (emas), har biri qavsda — NumPy dagi qoida.

Filtr natijasi ham jadval — uni darhol rasmga aylantirish mumkin. Yangi avtomat mashinalar har viloyatdagi e'lonlarning qancha qismi?

python5 qator
ulush = (yangi_avtomat.groupby(avto["viloyat"]).mean() * 100).sort_values()
ax = ulush.plot(kind="barh", color="#1a73e8", title="2020+ avtomat mashinalar ulushi, %")
ax.axvline(yangi_avtomat.mean() * 100, color="#c5221f", linestyle="--", label="butun respublika")
ax.legend(loc="lower right")
plt.show()

Mask — True/False; uning o'rtachasi — True lar ulushi (5-bob). groupby(avto["viloyat"]) uni har viloyat uchun alohida hisobladi (14-bob). Qizil chiziq — umumiy ulush: undan o'ngdagi viloyatlarda yangi avtomat mashinalar ko'proq.

Qulay filtrlar: isin, between, query

python4 qator
vodiy = avto["viloyat"].isin(["Andijon", "Namangan", "Farg'ona"])
print("vodiy:", vodiy.sum())
print("2015–2018:", avto["yil"].between(2015, 2018).sum())
avto.query("yil >= 2022 and uzatma == 'Mexanika' and viloyat != 'Toshkent'")[["model", "yil", "viloyat"]].head()
Chiqish
vodiy: 266
2015–2018: 198
elon_idmodelyilviloyat
1003SPARK2024Namangan
1006COBALT2024Samarqand
1019Nexia 32024Buxoro
1040GENTRA2022Samarqand
1548SPARK2022Andijon
  • isin([...]) — ro'yxatdagi qiymatlardan biri: uchta | o'rniga.
  • between(a, b) — oraliq, ikkala chegara kiradi.
  • query("...") — shartni matn sifatida, ustun nomlari bilan. Uzun shartlarda o'qish oson; and/or ni bu yerda so'z bilan yozish mumkin, chunki query uni o'zi tarjima qiladi.

Matn bo'yicha filtr: .str

python4 qator
som_bilan = avto["narx"].str.contains("so'm")
mln_bilan = avto["narx"].str.contains("mln")
print("'so'm' bor:", som_bilan.sum(), "| 'mln' bor:", mln_bilan.sum(), "| faqat raqam:", (~som_bilan).sum())
avto.loc[mln_bilan, "narx"].head(3)
Chiqish
'so'm' bor: 447 | 'mln' bor: 89 | faqat raqam: 165
elon_idnarx
1006138 mln so'm
1007166 mln so'm
102468 mln so'm

.str — matnli ustun uchun asboblar to'plami: contains, startswith, lower, replace... Shu filtr bilan narx ustuni uch xil formatda yozilganini topdik: "123 500 000 so'm", "45 mln so'm" va oddiy raqam. 12-bobda uchalasini bitta songa aylantiramiz.

Ustunlarni tur bo'yicha tanlash

python2 qator
print(avto.select_dtypes("number").columns.tolist())
print(avto.select_dtypes("object").columns.tolist())
Chiqish
['yil']
['model', 'rang', 'probeg_km', 'uzatma', 'viloyat', 'narx']

select_dtypes — ustunlarni nomi bilan emas, turi bilan tanlash. 10-bobdagi describe aynan shu bilan son ustunlarni ajratadi.

Saralash va eng kattalari

python2 qator
print(avto.sort_values(["yil", "model"], ascending=[False, True])[["model", "yil"]].head(4))
avto.nsmallest(3, "yil")[["model", "yil", "viloyat"]]
Chiqish
           model   yil
elon_id               
1083      Cobalt  2024
1433       Damas  2024
1513       Damas  2024
1016      Malibu  2024
elon_idmodelyilviloyat
1002NEXIA 32012Toshkent
1020Captiva2012Buxoro
1021 Onix2012Buxoro

sort_values — bir nechta ustun bo'yicha, har biriga o'z yo'nalishi. nlargest / nsmallest — "eng ... N tasi" savoliga bitta qadam (7-bobdagi argsort + kesish o'rniga).

Tanlab o'zgartirish: bitta qadamda

Toshkentdan tashqaridagi e'lonlarning uzatma ustuniga "?" belgisini qo'ymoqchimiz (masalan, ular qayta tekshirilishi kerak). Ikki yozish usuli bor, va faqat bittasi ishlaydi:

python10 qator
import warnings

nusxa = avto.copy()
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    nusxa[nusxa["viloyat"] != "Toshkent"]["uzatma"] = "?"
print("zanjir bilan:", (nusxa["uzatma"] == "?").sum(), "ta o'zgardi")

nusxa.loc[nusxa["viloyat"] != "Toshkent", "uzatma"] = "?"
print("loc bilan:   ", (nusxa["uzatma"] == "?").sum(), "ta o'zgardi")
Chiqish
zanjir bilan: 0 ta o'zgardi
loc bilan:    541 ta o'zgardi

Birinchi yozuv (df[shart]["ustun"] = ...) — zanjirli indekslash: df[shart] avval yangi jadval (nusxa) yasaydi, qiymat o'sha nusxaga yoziladi va darhol yo'qoladi. Asl jadval o'zgarmadi — 0 ta. pandas bunda ogohlantirish (SettingWithCopyWarning) beradi; biz uni bu yerda yashirdik, natijani ko'rsatish uchun. Real kodda bu ogohlantirishni hech qachon e'tiborsiz qoldirmang.

To'g'ri yo'l — bitta loc: qator sharti va ustun nomi bir qavs ichida. Shunda pandas aynan asl jadvalga yozadi.

Xulosa

  • loc — yorliq bo'yicha (kesishda oxiri kiradi), iloc — o'rin bo'yicha (oxiri kirmaydi). Odatda loc.
  • loc[shart, ustunlar] — qator va ustunni bitta qadamda.
  • isin, between (chegaralar kiradi), query("..."), .str.contains.
  • select_dtypes — ustunlarni turi bo'yicha.
  • sort_values (bir nechta ustun), nlargest / nsmallest.
  • O'zgartirish — faqat df.loc[shart, "ustun"] = qiymat; df[shart]["ustun"] = ... — jim xato.

Mashqlar

  1. Samarqanddagi oq rangli mashinalar nechta? Ularning modeli va yili.
  2. iloc bilan oxirgi 3 qator va oxirgi 2 ustunni oling.
  3. query bilan: 2018 dan eski yoki probeg ko'rsatilmagan e'lonlar (maslahat: probeg_km.isna() query ichida ishlaydi).
  4. Nega avto.loc[1001:1003] 3 ta qator beradi, avto.iloc[0:3] ham 3 ta — lekin avto.iloc[1001:1003] bo'sh?

Javoblar

  1. avto.loc[(avto["viloyat"] == "Samarqand") & (avto["rang"] == "Oq"), ["model", "yil"]].
  2. avto.iloc[-3:, -2:].
  3. avto.query("yil < 2018 or probeg_km.isna()").
  4. iloc o'rin bilan ishlaydi: jadvalda 612 qator, 1001-o'rin yo'q — natija bo'sh (xato emas, kesish shunday).

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar