Python: деректен өз есебіңізге дейін 28-сабақ (барлығы 56)
Таңдау және сүзгілер: тек керегін қалдыру
Python курсының жиырма жетінші сабағы. Маска — «иә» мен «жоқтан» тұратын баған, әрі кесте сонымен тұтас сүзіледі, циклсіз. `df[маска]`, `.loc[маска, бағандар]`, `&`, `|`, `~` және міндетті жақшалар, `isin`, `between`, `str`, әрі сүзгіден кейін қайта саналмайтын белгілер.
Не үшін керек
Кесте сирек тұтас керек болады. Бір қаланың түбіртектері, айдың екінші жартысындағы шығыс, сомасы күдікті үлкен жолдар керек. Тізімде бұл — if бар цикл және жаңа тізім; кестеде — бір өрнек, әрі ол санап шығу емес, шарт болып оқылады.
Осы жерде жиырма бесінші сабақтың уәдесі де жабылады: loc пен iloc дәл жолдар сүзілген жерде ажырасады.
Бірден тұтас
vyborka.py файлы. Қаңтардағы он түбіртек және олардан керегін алудың сегіз тәсілі.
"""27-сабақ: керекті жолдар мен бағандарды алу.
Қаңтардағы он түбіртек. Солардан таңдаймыз — алдымен бағандарды, сосын
жолдарды, сосын екеуін бірден.
"""
import pandas as pd
rows = [
("2026-01-03", "Қостанай", "тамақ", 4200),
("2026-01-05", "Қостанай", "жанармай", 18500),
("2026-01-07", "Рудный", "тамақ", 2600),
("2026-01-09", "Қостанай", "байланыс", 4990),
("2026-01-12", "Астана", "тамақ", 7300),
("2026-01-15", "Қостанай", "жалдау", 95000),
("2026-01-18", "Рудный", "жанармай", 16200),
("2026-01-21", "Астана", "байланыс", 4990),
("2026-01-24", "Қостанай", "тамақ", 3100),
("2026-01-27", "Рудный", "жалдау", 62000),
]
df = pd.DataFrame(rows, columns=["day", "city", "kind", "amount"])
df["day"] = pd.to_datetime(df["day"])
print(df)
print()
print("== бағандар: біреуі және бірнешеуі")
print("df['amount'] →", type(df["amount"]).__name__)
print("df[['city', 'amount']] →", type(df[["city", "amount"]]).__name__)
print()
print("== маска — «иә» мен «жоқтан» тұратын баған")
big = df["amount"] > 10000
print(big.tolist())
print("келген жол:", int(big.sum()), "барлығынан", len(df))
print()
print("== жолдарды сүзу")
print(df[big])
print()
print("== екі шарт: & | ~ және міндетті жақшалар")
kostanay_food = (df["city"] == "Қостанай") & (df["kind"] == "тамақ")
print("Қостанай әрі тамақ:", int(kostanay_food.sum()))
print("тамақ емес:", int((~(df["kind"] == "тамақ")).sum()))
print("тамақ не байланыс:", int(df["kind"].isin(["тамақ", "байланыс"]).sum()))
print()
print("== жолдар мен бағандар бір өтінімде")
print(df.loc[kostanay_food, ["day", "amount"]])
print()
print("== тағы үш дайын шарт")
print("4000-нан 20000-ға дейін:", int(df["amount"].between(4000, 20000).sum()))
print("қаласы «Қ»-дан басталады:", int(df["city"].str.startswith("Қ").sum()))
print("айдың екінші жартысы:", int((df["day"] >= "2026-01-15").sum()))
print()
print("== сүзгіден кейін белгілер қайта саналмайды")
rudny = df[df["city"] == "Рудный"]
print("белгілер:", rudny.index.tolist())
print("loc[2]:", rudny.loc[2, "kind"], "| iloc[2]:", rudny.iloc[2]["kind"])
print()
print("== loc арқылы жазу")
df.loc[df["kind"] == "байланыс", "kind"] = "мобильді байланыс"
print(df["kind"].value_counts().to_dict())
Шығысы:
day city kind amount
0 2026-01-03 Қостанай тамақ 4200
1 2026-01-05 Қостанай жанармай 18500
2 2026-01-07 Рудный тамақ 2600
3 2026-01-09 Қостанай байланыс 4990
4 2026-01-12 Астана тамақ 7300
5 2026-01-15 Қостанай жалдау 95000
6 2026-01-18 Рудный жанармай 16200
7 2026-01-21 Астана байланыс 4990
8 2026-01-24 Қостанай тамақ 3100
9 2026-01-27 Рудный жалдау 62000
== бағандар: біреуі және бірнешеуі
df['amount'] → Series
df[['city', 'amount']] → DataFrame
== маска — «иә» мен «жоқтан» тұратын баған
[False, True, False, False, False, True, True, False, False, True]
келген жол: 4 барлығынан 10
== жолдарды сүзу
day city kind amount
1 2026-01-05 Қостанай жанармай 18500
5 2026-01-15 Қостанай жалдау 95000
6 2026-01-18 Рудный жанармай 16200
9 2026-01-27 Рудный жалдау 62000
== екі шарт: & | ~ және міндетті жақшалар
Қостанай әрі тамақ: 2
тамақ емес: 6
тамақ не байланыс: 6
== жолдар мен бағандар бір өтінімде
day amount
0 2026-01-03 4200
8 2026-01-24 3100
== тағы үш дайын шарт
4000-нан 20000-ға дейін: 6
қаласы «Қ»-дан басталады: 5
айдың екінші жартысы: 5
== сүзгіден кейін белгілер қайта саналмайды
белгілер: [2, 6, 9]
loc[2]: тамақ | iloc[2]: жалдау
== loc арқылы жазу
{'тамақ': 4, 'жанармай': 2, 'мобильді байланыс': 2, 'жалдау': 2}
Талдау
Баған және бағандар тізімі
df["amount"] — бұл Series, бір баған. df[["city", "amount"]] — екеуінен тұратын DataFrame: тік жақшаның ішінде тізім тұр, сондықтан жауап та кесте, тізімде бір ат болса да. Айырмашылық маңызды: Series пен DataFrame-нің әдістері әртүрлі, ал «неге істемейді» деген сұрақтың жартысы — кесте күткен жерде Series тұрғаны.
Маска — «иә» мен «жоқтан» тұратын баған
df["amount"] > 10000 «иә» не «жоқ» деп жауап бермейді. Ол бағанмен жауап береді: әр жолға бір жауап, сол белгілермен. Қалғанының бәрі содан:
big.sum()келген жолдарды санайды, өйткеніTrue— бұл бірлік (төртінші сабақ);df[big]Trueтұрған жолдарды қалдырады;- маска кестемен рет бойынша емес, белгі бойынша салыстырылады — pandas-тағының бәрі сияқты.
&, |, ~ және әшекей емес жақшалар
Екі шарт сөзбен емес, таңбамен қосылады: and орнына &, or орнына |, not орнына ~. Сөздер мұнда істемейді, әрі бұл қырсықтық емес: and бір ғана «иә» не «жоқ» жауабын сұрайды, ал бағанда ондай жауап он. Python мұны ашық айтады:
ValueError: The truth value of a Series is ambiguous.
Әр шарттың айналасындағы жақша міндетті, өйткені & салыстырудан бұрын орындалады: онсыз df["city"] == "Қостанай" & df["kind"] == "тамақ" деген өрнек df["city"] == ("Қостанай" & df["kind"]) == "тамақ" болып саналады да, жақша кінәлі екенін түсіндірмей құлайды.
Ұзын тізбектің орнына дайын шарттар
Күн сайын жазылатын үш нәрсе:
df["kind"].isin(["тамақ", "байланыс"])—(... == "тамақ") | (... == "байланыс")орнына, әрі тізім қандай ұзын болса да жарайды;df["amount"].between(4000, 20000)— екі салыстырудың орнына, шектері кіреді;df["city"].str.startswith("Қ")— қасындаstr.contains,str.lower,str.len: жолдар істей алатынның бәрі бағанда.strарқылы бар.
Жетіспейтін мәндер бөлек тексеріледі: df["amount"].isna() және .notna(). NaN-мен салыстыру әрқашан «жоқ» береді, тіпті NaN == NaN те, сондықтан оларды салыстырумен іздеудің пайдасы жоқ.
Жолдар мен бағандар бір өтінімде
df.loc[маска, ["day", "amount"]] — сол жағы жолдарды, оң жағы бағандарды таңдайды. Бұл df[маска][["day", "amount"]] нұсқасынан қысқа да, арзан да: екіншісі артығын лақтыру үшін ғана барлық бағаннан аралық кесте құрады.
Сөзбен жазатын түрі де бар: df.query("amount > 5000 and city == 'Қостанай'") — жол ішінде and мен or дәл осылай істейді. Ол өзіңіз жазған ұзын шарттарға ыңғайлы.
Онымен істеуге болмайтын нәрсе: сұраныс жолын пайдаланушы енгізген нәрседен құрастыру. query өрнекті код ретінде талдайды, әрі қойылған мәтін орындалады — бұл жиырма бірінші сабақтағы SQL-инъекциямен бір тесік. Мәндер @айнымалы арқылы беріледі (df.query("amount > @limit")), ал сырттан келген шартты маскамен құрған қауіпсіз: маска ештеңе орындамайды.
Сүзгіден кейін белгілер қайта саналмайды
Үш жолды сүздік — белгілер [2, 6, 9] күйінде қалды, өйткені бұл сол жолдардың өзі. Сондықтан мысалдағы loc[2] мен iloc[2] әртүрлі нәтиже береді: біреуі белгісі 2 болатын жолды, екіншісі реті бойынша үшіншісін сұрайды.
Бұл — жиырма бесінші сабақ «айырмашылық жолдар сүзілген бойда шығады» деген дәл сол орын. Қолтаңбалар кедергі келтірсе, reset_index(drop=True) жолдарды қайта нөмірлейді; мұндағы drop=True — әйтпесе ескі белгілер жаңа бағанға айналады.
loc арқылы жазу, ал сүзгі арқылы неге болмайды
Шартқа келген жолдарды белгілеу loc арқылы жүреді:
df.loc[df["kind"] == "байланыс", "kind"] = "мобильді байланыс"
df[df["kind"] == "байланыс"]["kind"] = "мобильді байланыс" нұсқасы қисынды көрінеді әрі ештеңе істемейді. df[маска] жаңа кесте қайтарады, ал меншіктеу бастапқысын емес, соны өзгертеді. pandas мұны байқап, ChainedAssignmentError деп ескертеді — ұзын шығыста оңай өтіп кететін ескерту, өйткені ол сіз бағдарламаның шығысын күтетін жерге түспейді.
Ереже қарапайым: = белгісінің сол жағында бір тік жақшадан көп нәрсе тұрса — бұл loc.
Сабақ картасы
Өз сөзіңізбен айтыңыз
Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптар — сабақтың соңында.
- Маска деген не және
df["amount"] > 10000неге «иә» де, «жоқ» та емес? - Екі шартты неге
andсөзімен емес,&таңбасымен қосады? - Сүзгіден кейін
loc[2]менiloc[2]неге әртүрлі жол бере алады?
Жаттығу
Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, түзету. Жауаптар — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.
1. Болжаңыз. Бұл бағдарлама не басып шығарады?
import pandas as pd
amounts = pd.Series([4200, 18500, 2600, 95000], index=["тамақ", "жанармай", "тамақ", "жалдау"])
mask = amounts > 5000
print(mask.tolist(), "| келгені:", int(mask.sum()))
print(amounts[mask].to_dict())
2. Бос орынды толтырыңыз. ... орнына шартты қойыңыз: қаласы Қостанай әрі сомасы 5000-нан көп.
# екі шарт, әрқайсысы өз жақшасында
import pandas as pd
df = pd.DataFrame({"city": ["Қостанай", "Рудный", "Қостанай"], "amount": [4200, 16200, 95000]})
print(df[...].to_string(index=False))
3. Түзетіңіз. Бағдарлама байланысты «мобильді байланысқа» ауыстыруға тиіс, бірақ кесте өзгермейді, ал шетте ChainedAssignmentError пайда болады.
# меншіктеу кестеге емес, көшірмеге кетеді
import pandas as pd
df = pd.DataFrame({"kind": ["тамақ", "байланыс"], "amount": [4200, 4990]})
df[df["amount"] > 4500]["kind"] = "мобильді байланыс"
print(df.to_string(index=False))
Тапсырма
Міндетті. Сабақтағы сол он түбіртекті алыңыз да, үш сұраққа циклмен емес, таңдаумен жауап беріңіз:
- Қостанайдағы 5000-нан қымбат түбіртектер — тек күні мен сомасы.
- Түбіртектерді белгілеңіз: сомасы 20000-нан болса —
ірі, әйтпесекәдімгі. Бағанды меншіктеумен қосыңыз, белгініlocарқылы қойыңыз. Қайсысы қанша екенін басып шығарыңыз. - Ірі түбіртектердің қалалар бойынша сомасы.
Күтілетін шығыс:
Қостанайда 5000-нан қымбат:
day amount
2026-01-05 18500
2026-01-15 95000
түбіртектің мөлшері:
мөлшері
кәдімгі 8
ірі 2
қалалар бойынша ірілері:
city
Рудный 62000
Қостанай 95000
Дайын болғаны: шығыс жол-жолымен сәйкес келеді; белгі = белгісінің сол жағындағы сүзгімен емес, df.loc[маска, "мөлшері"] арқылы қойылған; бірінші жауапта екі баған бір өтінімде таңдалған; сомалар циклмен емес, сүзілген кестені топтаумен алынған.
Өз деректеріңізде. Өз кестеңізді алып, оған үш шарт құрыңыз: біреуі қарапайым, біреуі екі бөліктен, біреуі isin не between арқылы. Әрқайсысына қанша жол келгенін басып шығарыңыз. Біреуіне нөл жол келсе — dtypes-ке қараңыз. Бағанда санның орнына жол тұрса, == барлық жолға үнсіз «жоқ» береді, ал > пен < TypeError-мен құлайды. Мұны шартты іріктеумен емес, сүзгіге дейінгі pd.to_numeric арқылы емдейді.
Қалауыңыз бойынша.
- Сол шартты
queryарқылы жазып, қайсысы оңай оқылатынын салыстырыңыз. df[маска].reset_index(drop=True)жасап, белгілерге не болғанын қараңыз.~маскақанша жол беретінін тексеріп, маскамен қосқанда кестенің ұзындығы шығатынына көз жеткізіңіз.
Жобада бұл қайда тұрады
Қазір қадам жоқ: жиынтыққа бес жол жетеді, әрі онда сүзетін ештеңе әзірге жоқ. Бірақ таңдау — келесі қадам содан жасалатын нәрсе: қатар бірнешеу болғанда, есеп «тек керекті жолдарды алудан» басталады, содан кейін ғана келесі сабақтағы топтау келеді.
Қарыздар. Шарттар бізде кодтың ішінде жазылады. Олар үшеуден асқанда, ат сұрайды — әрі қатар тұрған үш жақшадан гөрі жақсы оқылатын irileri(df) тәрізді функцияларға айналады.
Жауаптар
Жауаптарды көрсету
Сұрақтарға
- Маска — «иә» мен «жоқтан» тұратын баған, әр жолға бір жауап, сол белгілермен. Бағанды санмен салыстыру бағанды тұтас емес, әр мәнді салыстырады, сондықтан жауап та баған болып шығады.
- Өйткені
andбір жауап сұрайды, ал бағанда олар жол саны қанша болса, сонша.&— әр элементпен жұмыс істеп, дәл сондай баған қайтаратын таңба. Жақшалар да сол себепті керек:&салыстырудан бұрын орындалады. - Өйткені сүзгі белгілерді қайта санамайды: қалған жолдарда олар бұрынғыдай.
loc[2]белгісі 2 болатын жолды,iloc[2]реті бойынша үшіншісін сұрайды, ал сүзгіден кейін бұл әртүрлі жол.
Жаттығуға
- Салыстыру «иә» мен «жоқтан» тұратын баған береді,
sum()келгенін санайды, алamounts[mask]тек соларды қалдырады — белгілерімен бірге.
[False, True, False, True] | келгені: 2
{'жанармай': 18500, 'жалдау': 95000}
(df["city"] == "Қостанай") & (df["amount"] > 5000). Жақшалар міндетті, таңбасы — сөз емес,&.
import pandas as pd
df = pd.DataFrame({"city": ["Қостанай", "Рудный", "Қостанай"], "amount": [4200, 16200, 95000]})
print(df[(df["city"] == "Қостанай") & (df["amount"] > 5000)].to_string(index=False))
city amount
Қостанай 95000
df.loc[df["amount"] > 4500, "kind"] = "мобильді байланыс". Меншіктеу кестенің өзіне түсуге тиіс, алdf[маска]— бұл басқа кесте.
import pandas as pd
df = pd.DataFrame({"kind": ["тамақ", "байланыс"], "amount": [4200, 4990]})
df.loc[df["amount"] > 4500, "kind"] = "мобильді байланыс"
print(df.to_string(index=False))
kind amount
тамақ 4200
мобильді байланыс 4990
Тапсырмаға
Бірінші жауап — df.loc[маска, ["day", "amount"]]: жолдар мен бағандар бір өтінімде. Екіншісі — алдымен баған тұтасымен әдепкі мәнмен толтырылады, содан кейін шарт ақиқат жерде loc оны басып жазады; сонда белгісіз жол қалмайды. Үшіншісі — сүзгі және топтау: ірілерін іріктеп алып, содан кейін қалалар бойынша қосу.
Дереккөздер
- Индекстеу және дерек таңдау — маскалар,
loc,ilocжәне олардың ережелері. - Бағанның жолдық әдістері —
.strарқылы қолжетімдінің бәрі. - Көшірме ме, көрініс пе — сүзгі арқылы меншіктеу неге ештеңе өзгертпейді.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.