Python: деректен өз есебіңізге дейін 26-сабақ (барлығы 56)
DataFrame және Series: нөмірдің орнына қолтаңба
Python курсының жиырма бесінші сабағы. Жол белгісі бар кесте тізімше жауап бермейді: `loc` белгі бойынша, `iloc` нөмір бойынша алады, ал екі қатардың қосындысы рет бойынша емес, жыл бойынша есептеледі. `DataFrame` мен `Series`, индекс, тілімдер және өзі пайда болатын `NaN`.
Не үшін керек
Өткен сабақ ережемен аяқталды: кесте бар және оған бір сұрақтан көп қойылады — pandas алыңыз. Бұл сабақ сол кестенің неден жасалғаны туралы.
Тізімнен басты айырмашылығы — белгілер. Тізімде тек нөмір бар: үшінші элемент, жетінші. Кестеде баған аттары мен жол белгілері бар, әрі жауаптардың бәрі солармен бірге келеді. Шыңның жылы позиция емес, жыл болып қайтады. Екі қатар, біреуі қысқа болса да, жыл бойынша қосылады. Бағдарламаның қалай жазылатынын жылдамдық емес, дәл осы өзгертеді.
Бірден тұтас
tablica.py файлы. Үш елдегі инфляция, төрт жыл — Дүниежүзілік банктің дерегі, ондыққа дейін дөңгелектелген.
"""25-сабақ: кесте кесте болып тұрсын.
Үш елдегі инфляция, төрт жыл. Сол қатар кестеде бағандармен жатыр, жолдардың
белгісі бар, ал қалғанының бәрі сол белгілерге байланысты.
"""
import pandas as pd
# Инфляция, жылына %. Дүниежүзілік банктің дерегі, ондыққа дейін дөңгелектелген.
data = {
"KZ": [8.0, 15.0, 14.5, 8.7],
"UZ": [10.8, 11.4, 10.0, 9.6],
"RU": [6.7, 13.7, 5.9, 8.4],
}
df = pd.DataFrame(data, index=[2021, 2022, 2023, 2024])
df.index.name = "жыл"
print(df)
print()
print("== ол неден тұрады")
print("пішіні:", df.shape, "| бағандар:", list(df.columns))
print("жол белгілері:", df.index.tolist())
print(df.dtypes)
print()
print("== баған — бұл Series")
kz = df["KZ"]
print("түрі:", type(kz).__name__, "| белгілер:", kz.index.tolist())
print(kz)
print()
print("== белгі бойынша жол және нөмір бойынша жол")
print("loc[2022]:", df.loc[2022].to_dict())
print("iloc[1]: ", df.iloc[1].to_dict())
print("бір ұяшық:", df.loc[2023, "UZ"])
print("loc[2022:2024] жылдары:", df.loc[2022:2024].index.tolist(), "— соңы кіреді")
print("iloc[1:3] жылдары: ", df.iloc[1:3].index.tolist(), "— соңы кірмейді")
print()
print("== жаңа баған ескілерінен есептеледі")
df["орташа"] = df.mean(axis=1).round(2)
print(df)
print()
print("== қосу белгі бойынша жүреді, рет бойынша емес")
part = pd.Series([1.0, 2.0], index=[2023, 2024])
print(df["KZ"] - part)
Шығысы:
KZ UZ RU
жыл
2021 8.0 10.8 6.7
2022 15.0 11.4 13.7
2023 14.5 10.0 5.9
2024 8.7 9.6 8.4
== ол неден тұрады
пішіні: (4, 3) | бағандар: ['KZ', 'UZ', 'RU']
жол белгілері: [2021, 2022, 2023, 2024]
KZ float64
UZ float64
RU float64
dtype: object
== баған — бұл Series
түрі: Series | белгілер: [2021, 2022, 2023, 2024]
жыл
2021 8.0
2022 15.0
2023 14.5
2024 8.7
Name: KZ, dtype: float64
== белгі бойынша жол және нөмір бойынша жол
loc[2022]: {'KZ': 15.0, 'UZ': 11.4, 'RU': 13.7}
iloc[1]: {'KZ': 15.0, 'UZ': 11.4, 'RU': 13.7}
бір ұяшық: 10.0
loc[2022:2024] жылдары: [2022, 2023, 2024] — соңы кіреді
iloc[1:3] жылдары: [2022, 2023] — соңы кірмейді
== жаңа баған ескілерінен есептеледі
KZ UZ RU орташа
жыл
2021 8.0 10.8 6.7 8.50
2022 15.0 11.4 13.7 13.37
2023 14.5 10.0 5.9 10.13
2024 8.7 9.6 8.4 8.90
== қосу белгі бойынша жүреді, рет бойынша емес
жыл
2021 NaN
2022 NaN
2023 13.5
2024 6.7
dtype: float64
Талдау
Бір емес, екі нәрсе
DataFrame — кесте: аты бар бағандар және белгісі бар жолдар. Series — бір баған: мәндер және сол белгілер. Қалғанының бәрі осы екеуінен шығады.
df["KZ"] Series қайтарады, әрі оның белгілері кестенікімен бірдей: жылдар. Қай сан қай жылдікі екенін есте ұстауға тура келетін сандар тізімі емес, жылдарымен бірге келген сандар. Сондықтан kz.index.tolist() [0, 1, 2, 3] емес, [2021, 2022, 2023, 2024] басып шығарады.
df.dtypes — ол да Series: сол жағында баған аттары, оң жағында олардың түрлері. Осы шығыстың соңғы жолындағы dtype: object содан: түрлердің өзі сан емес, нысан, ал солардан құралған бағанның түрі — «кез келген нәрсе».
Индекс — бұл белгі, рет емес
Жол белгісі — ағылшынша label, pandas құжаттамасында солай аталады; бұл жерде ол жолдың аты деген сөз.
Біз index=[2021, 2022, 2023, 2024] деп бердік, сол сәттен бастап жолдың аты — жыл. «Нөлінші жол» емес, «екі мың жиырма бірінші». Индекске ат қоюға болады (df.index.name = "жыл"), сонда кесте бұрышында сол атпен басылады.
Бұдан бәрі сүрінетін айырмашылық шығады:
df.loc[2022]— белгі бойынша жол. 2022 жыл.df.iloc[1]— нөмір бойынша жол. Реті бойынша екінші.
Біздің кестеде бұл бір жол, әрі мысал дәл сондықтан қитұрқы: белгілер нөлден қатарынан жүрсе, айырмашылық көрінбейді. Ол жолдар сұрыпталған не сүзілген бойда пайда болады.
Екінші салдары — тілімдер. df.loc[2022:2024] үш жыл береді: белгіде соңы кіреді, өйткені адам тілінде «2022-ден 2024-ке дейін» дәл осыны білдіреді. df.iloc[1:3] екеуін береді: нөмірде соңы кірмейді, бесінші сабақтағы кәдімгі тізім тіліміндегідей. Бір жазу, екі түрлі ереже — өйткені сұрақтар да екі түрлі.
Ұяшық бір амалмен алынады: df.loc[2023, "UZ"] — алдымен жол белгісі, сосын баған аты.
Жаңа баған — цикл емес, өрнек
df["орташа"] = df.mean(axis=1).round(2) баған қосады. axis=1 дегені «жол бойымен»: әр жыл үшін үш ел бойынша санау. axis-сіз бағандар бойынша саналар еді — әр ел үшін барлық жылдың орташасы, ал бұл басқа сұрақ.
Жаңа атпен баған меншіктеу арқылы құрылады, бар атпен — ауыстырылады. df["ат"] = ... сөздіктей мінез көрсететін жалғыз жер осы.
Қолтаңбалар қосылады, қатарға тізілмейді
Сабақ содан жазылған басты нәрсе:
part = pd.Series([1.0, 2.0], index=[2023, 2024])
df["KZ"] - part
Нәтижесі — төрт жол, оның екеуі NaN. pandas «біріншіден біріншіні» шегермейді: ол белгілерді салыстырады. part-та 2021 мен 2022 жоқ — демек, ол жылдар үшін жауап та жоқ, оларда NaN тұрады.
Сегізінші сабақпен салыстырыңыз: онда zip екі қатарды жыл бойынша емес, позиция бойынша қосқан, қысқа қатар ұзынын үнсіз қиып тастаған, ал қате дұрыс жауапқа ұқсаған. Мұнда керісінше — белгілердің сәйкес келмегені бірден көрінеді, өйткені ол басылып тұр.
NaN — нөл де емес, кодыңыздағы жетіспеушілік те емес: бұл «мұнда сан жоқ» дегенді білдіретін мән. Арифметикада ол жұқпалы (NaN + 5 NaN береді), ал mean() үшін көрінбейді — ол оны жай ғана өткізіп жібереді. Онымен не істеу керегі — лас деректер туралы сабақтың тақырыбы, ал әзірге оның қайдан шыққанын білу жеткілікті: сәйкес келмеген белгілердан.
Ең алдымен нені қарау керек
Кесте басқа біреуден келгенде, алғашқы үш сұрақ әрқашан бірдей:
df.shape— қанша жол, қанша баған;df.dtypes— pandas әр бағанды не деп санайды (сан ба? жол ба? күн бе?);df.head(3)— ол сырттай қалай көрінеді.
Төртінші сұрақ — df.index: жолдар неге қарап белгіланған. Басқа біреудің кодындағы оғаштықтың жартысы ұмытылып кеткен индекспен түсіндіріледі.
Сабақ картасы
Өз сөзіңізбен айтыңыз
Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптар — сабақтың соңында.
locпенilocнесімен ерекшеленеді және тілім ережелері неге әртүрлі?df["KZ"]не қайтарады және ол сандар тізімінен несімен өзгеше?- Екі қатардың айырмасында
NaNқайдан шықты, екеуі де сан болса?
Жаттығу
Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, түзету. Жауаптар — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.
1. Болжаңыз. Бұл бағдарлама не басып шығарады?
import pandas as pd
rates = pd.Series({"KZ": 8.0, "UZ": 10.8, "RU": 6.7})
print(rates["UZ"])
print(rates.index.tolist(), "| орташа:", round(rates.mean(), 2))
print(rates[rates > 7])
2. Бос орынды толтырыңыз. ... орнына белгілерді қойыңыз, сонда айырма NaN бермей, екі жыл үшін де есептелсін.
# екі қатардың белгісі сәйкес келуге тиіс, әйтпесе шегеретін ештеңе жоқ
import pandas as pd
a = pd.Series([14.5, 8.7], index=[2023, 2024])
b = pd.Series([10.0, 9.6], index=[...])
print((a - b).round(1).tolist())
3. Түзетіңіз. Бағдарлама 2022 жылдың жолын алмақ болып, KeyError: 2022 қатесімен құлайды. Бір өтінімді ауыстырыңыз.
# кестедегі тік жақша баған туралы сұрайды, ал бізге жол керек
import pandas as pd
df = pd.DataFrame({"KZ": [15.0, 14.5], "UZ": [11.4, 10.0]}, index=[2022, 2023])
print(df[2022].to_dict())
Тапсырма
Міндетті. Сабақтағы сол инфляция кестесін алыңыз. Үш сұраққа жауап беріңіз, әрқайсысы циклмен емес, белгіге жүгінумен:
- Әр елде инфляцияның шыңы қай жылы болды және ол қанша (
idxmaxбелгіні, яғни жылды қайтарады). - Әр елде төрт жылда баға неше есе өсті: баған бойынша
(1 + i/100)көбейтіндісі. - Үш елдің орташасы бойынша қай жыл ең тыныш болды (
idxmin).
Күтілетін шығыс:
кесте:
KZ UZ RU
жыл
2021 8.0 10.8 6.7
2022 15.0 11.4 13.7
2023 14.5 10.0 5.9
2024 8.7 9.6 8.4
елдер бойынша шың:
KZ: 2022 (15.0)
UZ: 2022 (11.4)
RU: 2022 (13.7)
төрт жылда баға өсті:
KZ: 1.55 есе
UZ: 1.49 есе
RU: 1.39 есе
ең тыныш жыл: 2021 (орташа 8.50)
Дайын болғаны: шығыс жол-жолымен сәйкес келеді; шың жылы циклмен ізделмей, idxmax-тан алынған; баға өсімі пайыздардың қосындысымен емес, көбейтіндімен саналған; тыныш жыл бір елдің емес, үш елдің орташасы бойынша табылған.
Өз деректеріңізде. Жылдар не айлар бойынша өз қатарыңызды алыңыз — шығыс, сатылым, бағам, кез келгені — және одан мағыналы индексі бар Series құрыңыз. Шыңы мен түбін idxmax пен idxmin арқылы табыңыз. Жауап нөмірмен емес, белгімен қайтқанын тексеріңіз: нөмірмен қайтса, индексті бермегеніңіз.
Қалауыңыз бойынша.
- Жолдардың ретін өзгертіп (
df.sort_values("KZ")), одан кейінloc[2022]менiloc[1]қалай ажырасатынын қараңыз. - Сол кестені сөздіктер тізімінен құрып (
pd.DataFrame([{...}, {...}])), индекспен не болғанын салыстырыңыз. df.Tжасап, бағандар мен белгілердің неге айналғанын өзіңізге түсіндіріңіз.
Жобада бұл қайда тұрады
Жетінші қадам: жиынтық қатарды енді сөздікпен ұстамайды. sholu/esep.py одан жылдары белгіде тұрған DataFrame құрады, сонда үш цикл жоғалады:
- саны жоқ жылдарды өткізіп жіберуді үйретуге тура келген орташа —
mean()оларды өзі өткізеді; - жетіспейтін мәндерді санау —
isna().sum(); - жылды өзімен бірге сүйреп жүретін ең үлкенді іздеу —
idxmax()жылдың өзі.
Дискіге әзірге қол тигізген жоқпыз: CSV-ды бұрынғыдай csv модулі жазады және оқиды. read_csv пен to_csv — келесі сабақ.
Қарыздар. Жиынтықтың индексі — күн емес, сан түріндегі жыл; айлық қатар үшін бұл жетпейді, әрі кестедегі уақыт туралы сабақта нағыз күндерге көшуге тура келеді.
Жауаптар
Жауаптарды көрсету
Сұрақтарға
locбелгі бойынша,ilocнөмір бойынша сұрайды. Тілім ережелері әртүрлі, өйткені сұрақтар да әртүрлі: адам тілінде «2022-ден 2024-ке дейін» 2024-ті қамтиды, ал нөмір бойынша тілім — соңы кірмейтін кәдімгі Python тілімі.Series— баған: мәндер және белгілер. Тізімнен айырмашылығы — әр сан өз жылын біледі, әрі бұл білім сұрыптаудан, сүзгіден және арифметикадан кейін де сақталады.- Қолтаңбалардың сәйкес келмегенінен. Екінші қатарда 2021 мен 2022 жоқ, сондықтан ол жылдар үшін айырма да жоқ, ал pandas жолдарды үнсіз алып тастаудың немесе сандарды жылжытудың орнына
NaNқояды.
Жаттығуға
- Қолтаңба бойынша өтінім сан береді,
index— белгілер тізімін, ал салыстыру шарты дұрыс жолдарды сұрыптап алады:rates > 7«иә/жоқ» қатарын береді, кесте сонымен сүзіледі.
10.8
['KZ', 'UZ', 'RU'] | орташа: 8.5
KZ 8.0
UZ 10.8
dtype: float64
index=[2023, 2024]. Сандар өздігінен ештеңе білдірмейді: біріншіден бірінші емес, 2023-тен 2023 шегеріледі.
import pandas as pd
a = pd.Series([14.5, 8.7], index=[2023, 2024])
b = pd.Series([10.0, 9.6], index=[2023, 2024])
print((a - b).round(1).tolist())
[4.5, -0.9]
df[2022]аты2022болатын баған туралы сұрайды, ал ондай баған жоқ —KeyErrorсодан. Жолdf.loc[2022]арқылы алынады.
import pandas as pd
df = pd.DataFrame({"KZ": [15.0, 14.5], "UZ": [11.4, 10.0]}, index=[2022, 2023])
print(df.loc[2022].to_dict())
{'KZ': 15.0, 'UZ': 11.4}
Есте ұстауға тұрарлық ереже: кестедегі тік жақша — бағандар туралы, ал loc пен iloc — жолдар туралы.
Тапсырмаға
Баға өсімі — қосынды емес, көбейтінді: қатарынан 8 % және 15 % инфляция 23 % емес, 1.08 × 1.15 = 1.242, яғни 24,2 % береді. pandas-та бұл (1 + df / 100).prod() — бөлу мен қосу бүкіл кестеге бірден қолданылады, ал prod() баған бойынша көбейтеді.
idxmax() позицияны емес, белгіні қайтарады, сондықтан жыл өздігінен басылады. Индекс берілмеген болса, жол нөмірі қайтар еді — сонда оның қай жыл екенін еске түсіруге тура келер еді.
Дереккөздер
- pandas дерек құрылымдарына кіріспе —
SeriesбенDataFrameбірінші қолдан. - Индекстеу және дерек таңдау —
locпенilocбөлімі, тілім соңы туралы ережемен қоса. - Тұтыну бағасының инфляциясы, Дүниежүзілік банк — осы сабақтағы сандардың дереккөзі.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.