Yaliyomo

Wiki 12: Misingi ya AI na Data — Jupyter, NumPy, pandas, matplotlib

Mwezi 3 | Lengo kuu: Mwanafunzi aelewe AI/ML ni nini kwa lugha rahisi, afanye kazi ndani ya Jupyter notebook kwenye VS Code, na atumie NumPy, pandas na matplotlib kusoma, kusafisha, kuchambua na kuchora data halisi.


Maandalizi ya Mwalimu (soma kabla ya wiki kuanza)

Habari njema: wiki hii ni rahisi kuliko Wiki 11 — hakuna server wala auth. Lakini ni ulimwengu mpya (notebooks, data), kwa hiyo fanya kila cell mwenyewe kwanza.

  1. Soma:
  2. Sakinisha:

    • VS Code extension: Jupyter (mchapishaji: Microsoft). Inakuja na "Jupyter Keymap", "Jupyter Renderers" n.k.
    • Kwenye venv mpya ya wiki hii:
    powershell
    cd $HOME\Documents
    mkdir data_wiki12
    cd data_wiki12
    python -m venv .venv
    .\.venv\Scripts\Activate.ps1
    pip install ipykernel numpy pandas matplotlib
    
  3. Kuhusu versions: pandas inaweza kuwa 2.x au 3.x kulingana na siku ya kusakinisha. Code yote ya wiki hii inafanya kazi kwenye zote mbili. Tofauti pekee utakazoona kwenye output: pandas 3 inaonyesha dtype ya maandishi kama str (pandas 2: object), na type(df) kama pandas.DataFrame (pandas 2: pandas.core.frame.DataFrame). Usishtuke.

  4. Jaribu kwanza: unda notebook, chagua kernel ya .venv, endesha cell import pandas as pd; pd.__version__. Ukiona version, uko tayari.
  5. Maneno ya kuelewa: AI, Machine Learning, model, training, data, feature, label, prediction, notebook, cell, kernel, array, shape, vectorized, DataFrame, Series, index, NaN, groupby, plot.

Malengo ya Wiki (mwisho wa wiki mwanafunzi ataweza...)

  1. Kueleza kwa maneno rahisi AI, Machine Learning, model, training na prediction, na kwa nini data ndiyo msingi.
  2. Kuunda na kutumia Jupyter notebook ndani ya VS Code (cells, kernel, Markdown, restart).
  3. Kuunda NumPy arrays, kusoma shape/dtype, kufanya vectorized operations, boolean masks na axis.
  4. Kusoma CSV kwa pandas na kuchunguza data (head, info, describe, value_counts).
  5. Kuchagua columns/rows ([], loc, iloc), kuchuja kwa masharti, kuongeza columns, kupanga (sort_values).
  6. Kusafisha data: isna, fillna, dropna, drop_duplicates, astype, to_datetime.
  7. Kutumia groupby + sum/mean/count + agg.
  8. Kuchora line, bar, histogram na scatter plots kwa matplotlib, na kuhifadhi picha.
  9. Kuona "ML ndogo" kwa vitendo: kufit mstari (np.polyfit) na kutabiri.

Kipindi 1 — AI/ML kwa Lugha Rahisi, Jupyter, na NumPy

Mtiririko wa kipindi

  1. Marudio ya kazi ya nyumbani (Todo API: priority, overdue, delete me)
  2. AI ni nini? ML ni nini? (mazungumzo + mifano ya maisha ya kila siku)
  3. Jupyter kwenye VS Code: kuunda notebook, kernel, cells, Markdown
  4. NumPy: kwa nini? array dhidi ya list; shape, dtype
  5. Vectorized operations, takwimu (sum, mean...), boolean masks
  6. Arrays za 2D, axis, reshape
  7. Zoezi darasani
  8. Q&A + kazi ya nyumbani

Elezo kwa mwalimu (soma kwanza wewe)

AI (Artificial Intelligence / Akili Bandia) — neno pana: kompyuta kufanya kazi ambazo kwa kawaida zinahitaji akili ya binadamu (kutambua sauti, kutafsiri lugha, kupendekeza video, kujibu maswali kama ChatGPT/Claude).

Machine Learning (ML / Ujifunzaji wa Mashine) — sehemu ya AI. Badala ya programmer kuandika sheria zote kwa if/else, tunampa kompyuta mifano mingi (data) na inajifunza sheria (pattern) yenyewe.

  • Programu ya kawaida: sheria + data → jibu. (Sisi tunaandika sheria.)
  • Machine Learning: data + majibu → sheria (model). Kisha model inatumika kwa data mpya → jibu (prediction).

Maneno muhimu:

  • Data: mifano (mfano: nyumba 1000 na bei zake).
  • Features: sifa zinazotumika kutabiri (ukubwa wa nyumba, eneo, idadi ya vyumba).
  • Label / target: tunachotaka kutabiri (bei).
  • Training (kufundisha): mchakato wa model kujifunza kutoka data.
  • Model: kitu kilichojifunza — kwa ndani ni hesabu (namba nyingi) zinazogeuza features kuwa prediction.
  • Prediction: jibu la model kwa data mpya.
  • Aina kuu (kutaja tu): supervised (tuna majibu — mfano kutabiri bei), unsupervised (hatuna majibu — mfano kugawa wateja katika makundi), na deep learning / LLMs (models kubwa sana kama zinazoendesha chatbots).

Kwa nini tunaanza na NumPy/pandas? Kazi kubwa ya ML (takriban 80%) ni kuandaa data: kuisoma, kuisafisha, kuielewa, na kuichora. Models zenyewe (scikit-learn, PyTorch) zinategemea NumPy arrays na pandas DataFrames. Bila hizi, huwezi kuanza.

Jupyter notebook (.ipynb) — faili lenye cells. Kila cell ni code au Markdown (maandishi). Unaendesha cell moja moja (Shift+Enter) na output inaonekana chini yake. Kernel ni Python inayoendesha nyuma — inakumbuka variables zote za cells zilizoendeshwa. Ndiyo maana mpangilio wa kuendesha ni muhimu: ukiendesha cell ya 5 kabla ya ya 2, unaweza kupata error. Restart ya kernel inafuta kumbukumbu yote. Cell ikiishia na expression (bila print), notebook inaonyesha thamani yake yenyewe.

NumPy — library ya arrays za namba, zenye kasi kubwa (zimeandikwa kwa C ndani).

  • np.array([1, 2, 3]) — array; vitu vyote ni type moja (dtype), tofauti na list.
  • Vectorized: a * 2 inazidisha kila kipengele — hakuna for loop. Kwa list, [1,2,3] * 2 inarudia list!
  • shape — vipimo: (5,) ni 1D yenye vitu 5; (2, 3) ni 2D, safu (rows) 2, nguzo (columns) 3.
  • Boolean mask: a > 1000 inarudisha array ya True/False; a[a > 1000] inachagua vile vyenye True.
  • axis: kwenye 2D, axis=0 = shuka chini (kwa kila column), axis=1 = nenda kulia (kwa kila row).
  • NumPy 2 kwenye notebook: ukiandika a.sum() kama mstari wa mwisho wa cell, utaona np.int64(8800) — hiyo ni namba ya kawaida tu ikionyesha type yake. print(a.sum()) inaonyesha 8800.

Sema hivi kwa mwanafunzi

"Fikiria kumfundisha mtoto kutambua embe. Hukumpa sheria 'kama ni kijani-njano, umbo la yai, na harufu fulani...'. Unamwonyesha maembe mengi na kusema 'hili ni embe', na machungwa 'hili si embe'. Baadaye anatambua embe ambalo hajawahi kuliona. Hiyo ndiyo Machine Learning: mifano mingi → anajifunza → anatabiri kwa jipya."

"Kila siku unatumia ML: M-Pesa ikigundua muamala wa kutiliwa shaka, YouTube ikikupendekezea video, Google Translate ikitafsiri Kiswahili, simu ikifungua kwa sura yako."

"Model ni kama mpishi aliyejifunza kwa kupika mara elfu — sasa anajua kiasi cha chumvi bila kupima. Data ndiyo mazoezi yake. Data mbovu = mpishi mbovu. Ndiyo maana leo na wiki hii yote tunajifunza kushika data vizuri."

"Notebook ni kama daftari la maabara la mwanasayansi: unaandika jaribio (cell), unaona matokeo papo hapo, na unaandika maelezo pembeni (Markdown)."

"List ya Python ni kama mfuko wa sokoni — unaweza kuweka chochote: nyanya, simu, kitabu. NumPy array ni kama trei ya mayai — kila nafasi ni ya yai tu, lakini unaweza kubeba trei nzima kwa mkono mmoja na kuifanyia kitu kimoja kwa wakati mmoja."

Andika code hii live (share screen)

Hatua 1 — Notebook ya kwanza.

  1. VS Code → fungua folda data_wiki12.
  2. Ctrl+Shift+P → andika "Create: New Jupyter Notebook" → Enter.
  3. Juu kulia bonyeza "Select Kernel" → "Python Environments" → chagua .venv.
  4. Hifadhi kama kipindi1_numpy.ipynb (Ctrl+S).

Cell ya kwanza (Markdown — bonyeza + Markdown):

markdown
# Kipindi 1: NumPy
Leo tunajifunza arrays.

Cell ya code:

python
import numpy as np
np.__version__

Output: '2.x.x' (version yako). Bonyeza Shift+Enter.

Onyesha: (a) namba [1] pembeni ya cell — mpangilio wa kuendesha; (b) kitufe Variables juu ya notebook; (c) Restart — kisha jaribu kuendesha cell isiyo ya kwanza → NameError: name 'np' is not defined. Sema: "Kernel imesahau. Endesha kutoka juu (Run All)."

Hatua 2 — List dhidi ya array.

python
bei_list = [3000, 2800, 1500, 1000, 500]
print(bei_list * 2)

bei = np.array(bei_list)
print(bei * 2)
print(bei + 100)

Output:

text
[3000, 2800, 1500, 1000, 500, 3000, 2800, 1500, 1000, 500]
[6000 5600 3000 2000 1000]
[3100 2900 1600 1100  600]

Sema: "List imejirudia; array imezidisha kila bei. Hiyo ndiyo vectorized — hakuna for."

Hatua 3 — Sifa za array na takwimu.

python
print(type(bei), bei.dtype, bei.shape, bei.ndim)
print("jumla:", bei.sum())
print("wastani:", bei.mean())
print("kubwa:", bei.max(), "ndogo:", bei.min())
print("std:", bei.std().round(1))

Output:

text
<class 'numpy.ndarray'> int64 (5,) 1
jumla: 8800
wastani: 1760.0
kubwa: 3000 ndogo: 500
std: 985.1

Hatua 4 — Boolean masks.

python
print(bei > 1000)
print(bei[bei > 1000])
print((bei > 1000).sum(), "bidhaa zina bei zaidi ya 1000")

Output:

text
[ True  True  True False False]
[3000 2800 1500]
3 bidhaa zina bei zaidi ya 1000

Eleza: True inahesabiwa kama 1, False kama 0 — ndiyo maana .sum() inahesabu.

Hatua 5 — Mfano halisi: alama za wanafunzi.

python
alama = np.array([45, 78, 62, 90, 33, 71, 85, 55])
print("Wastani:", alama.mean())
print("Median:", np.median(alama))
print("Waliofaulu (>=50):", (alama >= 50).sum())
print(np.where(alama >= 50, "Amefaulu", "Ameshindwa"))
print("Baada ya bonus 10%:", np.round(alama * 1.1).astype(int))

Output:

text
Wastani: 64.875
Median: 66.5
Waliofaulu (>=50): 6
['Ameshindwa' 'Amefaulu' 'Amefaulu' 'Amefaulu' 'Ameshindwa' 'Amefaulu'
 'Amefaulu' 'Amefaulu']
Baada ya bonus 10%: [50 86 68 99 36 78 94 61]

Hatua 6 — Arrays za 2D na axis. Joto la wiki moja kwa miji miwili:

python
joto = np.array([
    [30, 31, 32, 31, 33, 34, 32],   # Dar es Salaam
    [24, 25, 23, 22, 26, 27, 25],   # Arusha
])
print(joto.shape)          # (2, 7) -> miji 2, siku 7
print(joto[0])             # Dar, siku zote
print(joto[:, 0])          # siku ya kwanza, miji yote
print(joto[1, 6])          # Arusha, siku ya 7
print("Wastani kwa mji:", joto.mean(axis=1).round(1))
print("Kubwa kwa siku:", joto.max(axis=0))

Output:

text
(2, 7)
[30 31 32 31 33 34 32]
[30 24]
25
Wastani kwa mji: [31.9 24.6]
Kubwa kwa siku: [30 31 32 31 33 34 32]

Chora ubaoni (au kwenye Markdown cell):

text
            axis=1  →  (kwa kila row)
          ┌──────────────────────┐
axis=0  │ │ 30 31 32 31 33 34 32 │  Dar
   ↓    │ │ 24 25 23 22 26 27 25 │  Arusha
          └──────────────────────┘

Hatua 7 — Kuunda arrays haraka.

python
print(np.arange(12).reshape(3, 4))
print(np.zeros((2, 3)))
print(np.linspace(0, 1, 5))
rng = np.random.default_rng(42)
print(rng.integers(1, 7, size=10))   # kurusha kete mara 10

Output:

text
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[0. 0. 0.]
 [0. 0. 0.]]
[0.   0.25 0.5  0.75 1.  ]
[1 5 4 3 3 6 1 5 2 1]

Sema: "Namba 42 ndani ya default_rng(42) ni 'seed' — inafanya 'random' ijirudie sawa kila mara — muhimu kwenye ML ili majaribio yalinganishwe."

Maswali ya kumuuliza mwanafunzi

  1. Tofauti ya programu ya kawaida na ML? — Kawaida: tunaandika sheria. ML: tunatoa data + majibu, kompyuta inajifunza sheria.
  2. Kwenye kutabiri bei ya nyumba, features ni nini na label ni nini? — Features: ukubwa, eneo, vyumba... Label: bei.
  3. Taja mfano mmoja wa ML unaoutumia kila siku. — (Jibu lolote la busara: mapendekezo ya YouTube, spam filter ya email, Google Translate...)
  4. Kernel ni nini? Ukiirestart nini kinatokea? — Python inayoendesha notebook; restart inafuta variables zote.
  5. [1,2,3] * 2 dhidi ya np.array([1,2,3]) * 2? — List: [1,2,3,1,2,3]. Array: [2 4 6].
  6. Array yenye shape (3, 4) ina vitu vingapi? — 12.
  7. joto.mean(axis=0) inarudisha vitu vingapi kwa array ya (2, 7)? — 7 (wastani wa kila siku/column).
  8. Kwa nini (alama >= 50).sum() inahesabu waliofaulu? — True = 1, False = 0.

Makosa ya kawaida

Kosa Ujumbe / dalili Suluhisho
Kernel haijachaguliwa / ni Python isiyo ya venv ModuleNotFoundError: No module named 'numpy' "Select Kernel" → .venv; hakikisha pip install numpy ndani ya venv
VS Code inaomba kusakinisha ipykernel Popup: "Running cells with '.venv' requires the ipykernel package" Bonyeza Install au pip install ipykernel
Kuendesha cells nje ya mpangilio NameError: name 'np' is not defined Restart + Run All
Kuchanganya types kwenye array np.array([1, "2", 3.0]) → ['1' '2' '3.0'] (dtype <U32 — maandishi!) Hakikisha data ni namba; astype(float)
Kutumia and/or kwenye arrays ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() Tumia &, \| na mabano: (a > 1) & (a < 5)
Shapes zisizolingana ValueError: operands could not be broadcast together with shapes (3,) (4,) Hakikisha arrays zina urefu sawa
reshape isiyowezekana ValueError: cannot reshape array of size 12 into shape (5,3) Bidhaa ya vipimo = idadi ya vitu (3×4=12)
Kushangaa np.int64(8800) Output ya cell inaonyesha np.int64(...) Ni kawaida kwa NumPy 2; tumia print(...) au int(...)

Zoezi darasani

Zoezi 1.1 — Mauzo ya siku 7 (TSh elfu): [120, 95, 140, 80, 160, 210, 175]. Kwa NumPy tafuta: jumla, wastani, siku (index) yenye mauzo makubwa zaidi (argmax), na siku ngapi zilivuka 130.

Zoezi 1.2 — Geuza joto la Celsius [30, 25, 18, 35, 22] kuwa Fahrenheit (F = C * 9/5 + 32) bila loop.

Zoezi 1.3 — Alama za wanafunzi 4 katika masomo 3:

python
alama = np.array([[70, 85, 60],
                  [55, 40, 75],
                  [90, 95, 88],
                  [65, 70, 50]])

Tafuta: (a) wastani wa kila mwanafunzi, (b) wastani wa kila somo, (c) mwanafunzi (index) bora, (d) alama zote zilizo chini ya 60.

Zoezi 1.4 (fikiri) — Andika kwenye Markdown cell: mfano mmoja wa tatizo la Tanzania linaloweza kutatuliwa kwa ML. Features ni zipi? Label ni nini?

Jibu

1.1

python
mauzo = np.array([120, 95, 140, 80, 160, 210, 175])
print(mauzo.sum())             # 980
print(mauzo.mean())            # 140.0
print(mauzo.argmax())          # 5  (siku ya 6 -> 210)
print((mauzo > 130).sum())     # 4

1.2

python
c = np.array([30, 25, 18, 35, 22])
print(c * 9 / 5 + 32)          # [86.  77.  64.4 95.  71.6]

1.3

python
print(alama.mean(axis=1).round(1))   # [71.7 56.7 91.  61.7]
print(alama.mean(axis=0))            # [70.   72.5  68.25]
print(alama.mean(axis=1).argmax())   # 2
print(alama[alama < 60])             # [55 40 50]

1.4 (mfano) — Kutabiri mavuno ya mahindi kwa shamba. Features: kiasi cha mvua, aina ya udongo, mbolea iliyotumika, ukubwa wa shamba, mkoa. Label: magunia kwa ekari. (Mifano mingine: kutabiri bei ya mazao sokoni, kutambua ugonjwa wa mihogo kwa picha ya jani, kugundua udanganyifu wa miamala ya simu.)


Kipindi 2 — pandas: Kusoma, Kuchunguza, Kuchuja, na Kusafisha Data

Mtiririko wa kipindi

  1. Marudio ya kazi ya nyumbani (NumPy)
  2. pandas ni nini: DataFrame na Series
  3. Kuunda mauzo.csv na read_csv; head, shape, info, describe
  4. Kuchagua: columns, loc, iloc, value_counts, unique
  5. Kuchuja kwa masharti (&, \|, isin)
  6. Kusafisha: isna, fillna, dropna, drop_duplicates, astype, to_datetime
  7. Columns mpya, sort_values, groupby
  8. Zoezi darasani
  9. Q&A + kazi ya nyumbani

Elezo kwa mwalimu (soma kwanza wewe)

pandas ni library ya data za mezani (tables) — fikiria "Excel ndani ya Python", lakini yenye nguvu zaidi na inayoweza kurudiwa (reproducible).

  • DataFrame — table nzima: rows na columns, kila column ina jina.
  • Series — column moja (au row moja) — kimsingi ni NumPy array yenye index (lebo za rows).
  • Index — lebo za rows (kwa default 0, 1, 2...).

Kuchagua:

  • df["col"] → Series (column moja). df[["a", "b"]] (mabano mawili!) → DataFrame.
  • df.loc[row_label, col_label] — kwa majina/lebo. Slicing ya loc inajumuisha mwisho: df.loc[2:4] = rows 2, 3, 4.
  • df.iloc[row_pos, col_pos] — kwa nafasi (namba kama list). df.iloc[2:4] = rows 2, 3 (mwisho haujumuishwi).

Kuchuja: df[df["idadi"] > 15] — ndani ni boolean mask (kama NumPy!). Masharti mengi: & (na), | (au), ~ (si), kila sharti ndani ya mabano.

Data inayokosekana (missing): pandas inaonyesha kama NaN (Not a Number). Column ya namba yenye NaN inakuwa float64 (ndiyo maana idadi inaonekana 12.0).

  • df.isna().sum() — hesabu NaN kwa kila column.
  • df["col"].fillna(thamani) — jaza. Kwa namba, mara nyingi median (haiathiriwi sana na thamani za ajabu kama mean).
  • df.dropna() — futa rows zenye NaN. Tumia kwa uangalifu — unapoteza data.
  • Muhimu (pandas 2/3, Copy-on-Write): andika df["col"] = df["col"].fillna(...). Usitumie df["col"].fillna(..., inplace=True) — kwenye pandas mpya haibadilishi df na inatoa warning.

Duplicates: df.duplicated().sum(), df.drop_duplicates().

groupby — "gawa, hesabu, unganisha" (split–apply–combine): df.groupby("mkoa")["jumla"].sum() = "kwa kila mkoa, jumla ya mauzo". Ni kama Pivot Table ya Excel. agg inaruhusu hesabu nyingi kwa mara moja.

Tabia muhimu: operesheni nyingi za pandas zinarudisha DataFrame mpya na hazibadilishi ya zamani. df.drop_duplicates() peke yake haibadilishi df — lazima df = df.drop_duplicates(). Hili ndilo kosa la kwanza la kila mwanzilishi.

Sema hivi kwa mwanafunzi

"DataFrame ni kama daftari la mauzo la duka: kila mstari ni muamala mmoja, kila safu (column) ni taarifa moja — tarehe, bidhaa, idadi, bei. Series ni safu moja tu, mfano 'idadi' yote."

"loc ni kumtafuta mtu kwa jina lake; iloc ni kumtafuta kwa namba ya kiti chake darasani."

"Data ya kweli huwa chafu — mtu alisahau kuandika idadi, mwingine aliandika muamala mara mbili. Kusafisha data ni kama kuchambua mchele kabla ya kupika: ukiacha mawe, chakula chote kinaharibika."

"groupby ni kama kumwambia karani: 'Gawa risiti hizi kwa mkoa, kisha nijumlishie kila rundo.'"

Andika code hii live (share screen)

Unda notebook mpya kipindi2_pandas.ipynb (kernel .venv).

Hatua 1 — Kuunda data. Cell ya kwanza (magic %%writefile inaandika faili; lazima iwe mstari wa kwanza wa cell):

python
%%writefile mauzo.csv
tarehe,mkoa,bidhaa,aina,idadi,bei_moja
2027-01-04,Dar es Salaam,Sukari,Chakula,12,3000
2027-01-04,Arusha,Mchele,Chakula,8,2800
2027-01-04,Mwanza,Sabuni,Usafi,15,1500
2027-01-05,Dar es Salaam,Daftari,Shule,30,1000
2027-01-05,Dodoma,Kalamu,Shule,,500
2027-01-05,Arusha,Sukari,Chakula,10,3000
2027-01-06,Mwanza,Mchele,Chakula,20,2800
2027-01-06,Dar es Salaam,Sabuni,Usafi,9,1500
2027-01-06,,Daftari,Shule,25,1000
2027-01-07,Dodoma,Sukari,Chakula,7,3000
2027-01-07,Dar es Salaam,Kalamu,Shule,40,500
2027-01-07,Arusha,Sabuni,Usafi,,1500
2027-01-08,Mwanza,Sukari,Chakula,14,3000
2027-01-08,Dar es Salaam,Mchele,Chakula,18,2800
2027-01-08,Dar es Salaam,Mchele,Chakula,18,2800
2027-01-08,Dodoma,Daftari,Shule,12,1000

Output: Writing mauzo.csv. Fungua mauzo.csv kwenye VS Code — mwonyeshe: "Angalia: Kalamu ya Dodoma haina idadi, row moja haina mkoa, na mstari wa Mchele wa tarehe 8 umeandikwa mara mbili. Hii ni data chafu kwa makusudi."

Hatua 2 — Kusoma na kuchunguza.

python
import pandas as pd

df = pd.read_csv("mauzo.csv")
df.head()

Output (table nzuri kwenye notebook):

text
       tarehe           mkoa   bidhaa     aina  idadi  bei_moja
0  2027-01-04  Dar es Salaam   Sukari  Chakula   12.0      3000
1  2027-01-04         Arusha   Mchele  Chakula    8.0      2800
2  2027-01-04         Mwanza   Sabuni    Usafi   15.0      1500
3  2027-01-05  Dar es Salaam  Daftari    Shule   30.0      1000
4  2027-01-05         Dodoma   Kalamu    Shule    NaN       500
python
print(df.shape)
df.info()

Output:

text
(16, 6)
<class 'pandas.DataFrame'>
RangeIndex: 16 entries, 0 to 15
Data columns (total 6 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   tarehe    16 non-null     str    
 1   mkoa      15 non-null     str    
 2   bidhaa    16 non-null     str    
 3   aina      16 non-null     str    
 4   idadi     14 non-null     float64
 5   bei_moja  16 non-null     int64  
dtypes: float64(1), int64(1), str(4)
memory usage: 900.0 bytes

(pandas 2.x inaonyesha object badala ya str — maana ni ileile: maandishi.)

Uliza: "info inatuambia nini kuhusu data chafu?" → mkoa 15/16, idadi 14/16 — kuna missing.

python
df.describe()

Output:

text
           idadi     bei_moja
count  14.000000    16.000000
mean   17.000000  1981.250000
std     9.323255   993.457766
min     7.000000   500.000000
25%    10.500000  1000.000000
50%    14.500000  2150.000000
75%    19.500000  2850.000000
max    40.000000  3000.000000

Eleza 50% = median.

Hatua 3 — Kuchagua.

python
df["bidhaa"].head(3)
text
0    Sukari
1    Mchele
2    Sabuni
Name: bidhaa, dtype: str
python
print(type(df["bidhaa"]), type(df[["bidhaa", "idadi"]]))
df[["bidhaa", "idadi"]].head(3)
text
<class 'pandas.Series'> <class 'pandas.DataFrame'>
   bidhaa  idadi
0  Sukari   12.0
1  Mchele    8.0
2  Sabuni   15.0
python
df["mkoa"].value_counts()
text
mkoa
Dar es Salaam    6
Arusha           3
Mwanza           3
Dodoma           3
Name: count, dtype: int64
python
df.loc[2:4, ["mkoa", "bidhaa"]]      # lebo 2 hadi 4 (4 imejumuishwa)
text
            mkoa   bidhaa
2         Mwanza   Sabuni
3  Dar es Salaam  Daftari
4         Dodoma   Kalamu
python
df.iloc[-1]                          # row ya mwisho
text
tarehe      2027-01-08
mkoa            Dodoma
bidhaa         Daftari
aina             Shule
idadi             12.0
bei_moja          1000
Name: 15, dtype: object

Hatua 4 — Kuchuja.

python
df[df["idadi"] > 15]
text
        tarehe           mkoa   bidhaa     aina  idadi  bei_moja
3   2027-01-05  Dar es Salaam  Daftari    Shule   30.0      1000
6   2027-01-06         Mwanza   Mchele  Chakula   20.0      2800
8   2027-01-06            NaN  Daftari    Shule   25.0      1000
10  2027-01-07  Dar es Salaam   Kalamu    Shule   40.0       500
13  2027-01-08  Dar es Salaam   Mchele  Chakula   18.0      2800
14  2027-01-08  Dar es Salaam   Mchele  Chakula   18.0      2800
python
df[(df["aina"] == "Chakula") & (df["idadi"] >= 12)]
text
        tarehe           mkoa  bidhaa     aina  idadi  bei_moja
0   2027-01-04  Dar es Salaam  Sukari  Chakula   12.0      3000
6   2027-01-06         Mwanza  Mchele  Chakula   20.0      2800
12  2027-01-08         Mwanza  Sukari  Chakula   14.0      3000
13  2027-01-08  Dar es Salaam  Mchele  Chakula   18.0      2800
14  2027-01-08  Dar es Salaam  Mchele  Chakula   18.0      2800
python
df[df["mkoa"].isin(["Arusha", "Dodoma"])].shape
text
(6, 6)

Hatua 5 — Kusafisha.

python
df.isna().sum()
text
tarehe      0
mkoa        1
bidhaa      0
aina        0
idadi       2
bei_moja    0
dtype: int64
python
df[df.isna().any(axis=1)]          # rows zenye tatizo
text
        tarehe    mkoa   bidhaa   aina  idadi  bei_moja
4   2027-01-05  Dodoma   Kalamu  Shule    NaN       500
8   2027-01-06     NaN  Daftari  Shule   25.0      1000
11  2027-01-07  Arusha   Sabuni  Usafi    NaN      1500
python
print("Duplicates:", df.duplicated().sum())
df = df.drop_duplicates()

median_idadi = df["idadi"].median()
print("Median ya idadi:", median_idadi)
df["idadi"] = df["idadi"].fillna(median_idadi)
df["mkoa"] = df["mkoa"].fillna("Haijulikani")

df["idadi"] = df["idadi"].astype(int)
df["tarehe"] = pd.to_datetime(df["tarehe"])

print("NaN zilizobaki:", df.isna().sum().sum())
print(df.shape)
text
Duplicates: 1
Median ya idadi: 14.0
NaN zilizobaki: 0
(15, 6)

Jadili: "Je, kujaza idadi kwa median ni sahihi kila mara? Hapana — ni uamuzi. Ingeweza kuwa bora kumuuliza mwenye duka. Kwenye data science, maamuzi haya lazima yaandikwe (Markdown cell!)."

Hatua 6 — Column mpya, sort, groupby.

python
df["jumla"] = df["idadi"] * df["bei_moja"]
df.sort_values("jumla", ascending=False).head(3)
text
       tarehe           mkoa  bidhaa     aina  idadi  bei_moja  jumla
6  2027-01-06         Mwanza  Mchele  Chakula     20      2800  56000
13 2027-01-08  Dar es Salaam  Mchele  Chakula     18      2800  50400
12 2027-01-08         Mwanza  Sukari  Chakula     14      3000  42000
python
df.groupby("mkoa")["jumla"].sum().sort_values(ascending=False)
text
mkoa
Dar es Salaam    149900
Mwanza           120500
Arusha            73400
Dodoma            40000
Haijulikani       25000
Name: jumla, dtype: int64
python
df.groupby("aina").agg(
    mauzo=("jumla", "sum"),
    wastani_idadi=("idadi", "mean"),
    miamala=("jumla", "count"),
)
text
          mauzo  wastani_idadi  miamala
aina                                   
Chakula  257800      12.714286        7
Shule     94000      24.200000        5
Usafi     57000      12.666667        3
python
print("Mauzo yote:", df["jumla"].sum())
df.to_csv("mauzo_safi.csv", index=False)
text
Mauzo yote: 408800

Sema: "Tumehifadhi data safi — Kipindi 3 tutaichora."

Maswali ya kumuuliza mwanafunzi

  1. Tofauti ya df["idadi"] na df[["idadi"]]? — Ya kwanza Series, ya pili DataFrame (column moja).
  2. df.loc[2:4] inarudisha rows ngapi? df.iloc[2:4]? — loc: 3 (2,3,4). iloc: 2 (2,3).
  3. Kwa nini column idadi ilikuwa 12.0 (float) mwanzoni? — Kwa sababu ina NaN, na NaN ni float.
  4. Kwa nini tunaandika df = df.drop_duplicates()? — Inarudisha DataFrame mpya; bila kuihifadhi, df haibadiliki.
  5. Kwa nini kujaza kwa median badala ya mean? — Median haivutwi sana na thamani za ajabu (mfano Kalamu 40).
  6. Unachujaje "Chakula AU Usafi"? — df[(df["aina"] == "Chakula") | (df["aina"] == "Usafi")] au df[df["aina"].isin(["Chakula", "Usafi"])].
  7. groupby("mkoa")["jumla"].sum() kwa maneno? — "Kwa kila mkoa, jumlisha mauzo."

Makosa ya kawaida

Kosa Ujumbe / dalili Suluhisho
Jina la column si sahihi (herufi kubwa/nafasi) KeyError: 'Idadi' df.columns kuona majina halisi
Faili halipo / folda tofauti FileNotFoundError: [Errno 2] No such file or directory: 'mauzo.csv' Notebook inaanzia kwenye folda yake; hakikisha CSV iko hapo
and badala ya & ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). (sharti1) & (sharti2)
Kusahau mabano kwenye masharti TypeError: Cannot perform 'rand_' with a dtyped [int64] array and scalar of type [bool] (au ujumbe unaofanana) (df["a"] > 1) & (df["b"] < 5)
df.drop_duplicates() bila kuhifadhi Shape haibadiliki df = df.drop_duplicates()
fillna(..., inplace=True) kwenye column FutureWarning/ChainedAssignmentError na data haibadiliki df["col"] = df["col"].fillna(...)
astype(int) kabla ya kujaza NaN IntCastingNaNError: Cannot convert non-finite values (NA or inf) to integer Jaza NaN kwanza
%%writefile isiyo mstari wa kwanza UsageError: Line magic function%%writefilenot found. %%writefile iwe mstari wa kwanza wa cell
Kubadilisha "nakala" ya DataFrame iliyochujwa SettingWithCopyWarning (pandas 2) / mabadiliko hayaonekani Tumia .copy(): chakula = df[df["aina"] == "Chakula"].copy()

Zoezi darasani

Tumia df safi (au pd.read_csv("mauzo_safi.csv", parse_dates=["tarehe"])).

Zoezi 2.1 — Onyesha miamala yote ya Dar es Salaam ambayo jumla ni zaidi ya 20,000.

Zoezi 2.2 — Bidhaa gani iliuza idadi kubwa zaidi kwa jumla? (dokezo: groupby + idxmax)

Zoezi 2.3 — Tengeneza column ukubwa yenye "Kubwa" kama jumla >= 30000, vinginevyo "Ndogo" (dokezo: np.where). Hesabu kila kundi lina miamala mingapi.

Zoezi 2.4 — Mauzo ya jumla kwa kila tarehe. Siku gani ilikuwa bora?

Jibu
python
import numpy as np

# 2.1
df[(df["mkoa"] == "Dar es Salaam") & (df["jumla"] > 20000)]

(Kalamu ya Dar ina jumla 20000 kamili, hivyo haimo: > si >=.) Output:

text
       tarehe           mkoa   bidhaa     aina  idadi  bei_moja  jumla
0  2027-01-04  Dar es Salaam   Sukari  Chakula     12      3000  36000
3  2027-01-05  Dar es Salaam  Daftari    Shule     30      1000  30000
13 2027-01-08  Dar es Salaam   Mchele  Chakula     18      2800  50400
python
# 2.2
df.groupby("bidhaa")["idadi"].sum().idxmax()      # 'Daftari'  (30 + 25 + 12 = 67)

# 2.3
df["ukubwa"] = np.where(df["jumla"] >= 30000, "Kubwa", "Ndogo")
df["ukubwa"].value_counts()
# Ndogo    9
# Kubwa    6

# 2.4
kwa_siku = df.groupby("tarehe")["jumla"].sum()
print(kwa_siku)
print("Siku bora:", kwa_siku.idxmax().date(), "->", kwa_siku.max())

Output ya 2.4:

text
tarehe
2027-01-04     80900
2027-01-05     67000
2027-01-06     94500
2027-01-07     62000
2027-01-08    104400
Name: jumla, dtype: int64
Siku bora: 2027-01-08 -> 104400

(Miamala "Kubwa" ni: 56000, 50400, 42000, 36000, 30000, 30000 = 6.)


Kipindi 3 — matplotlib: Kuchora Data, na "ML Ndogo" ya Kwanza

Mtiririko wa kipindi

  1. Marudio ya kazi ya nyumbani
  2. Kwa nini kuchora? Aina za chati na wakati wa kutumia kila moja
  3. fig, ax = plt.subplots(); line plot ya mauzo kwa siku; titles, labels, savefig
  4. Bar (wima na mlalo), histogram, scatter
  5. df.plot(...) ya pandas; subplots mbili kwa pamoja
  6. "ML ndogo": masaa ya kusoma → alama; np.polyfit; kutabiri; kuchora mstari
  7. Zoezi darasani
  8. Q&A, kufunga Mwezi 3, kazi ya nyumbani

Elezo kwa mwalimu (soma kwanza wewe)

Kwa nini kuchora? Macho ya binadamu yanaona mwenendo (trend), tofauti, na thamani za ajabu (outliers) haraka zaidi kwenye picha kuliko kwenye table.

Swali Chati
Kitu kinabadilikaje kwa muda? Line
Kulinganisha makundi (mikoa, bidhaa) Bar (barh kama majina ni marefu)
Data imesambaaje (distribution)? Histogram
Je, vitu viwili vinahusiana? Scatter

matplotlib — mtindo tutakaotumia ("object-oriented"):

python
fig, ax = plt.subplots()   # fig = karatasi nzima, ax = eneo la chati moja
ax.plot(x, y)
ax.set_title(...); ax.set_xlabel(...); ax.set_ylabel(...)
fig.savefig("picha.png")

Kwenye notebook, chati inaonyeshwa yenyewe chini ya cell. Kwenye script ya kawaida (.py) unahitaji plt.show().

pandas ina njia fupi: series.plot(kind="bar") — ndani inatumia matplotlib na inarudisha ax.

"ML ndogo" — linear regression kwa mkono. Tuna data ya wanafunzi: masaa ya kusoma (feature) na alama (label). Tunataka mstari alama = a × masaa + b unaopita karibu zaidi na pointi zote. np.polyfit(x, y, 1) inatafuta a (mteremko/slope) na b (intercept) bora kwa "least squares" (inapunguza jumla ya makosa yaliyoraba). Hii ndiyo "training": kutoka data, tumepata namba mbili (a, b) — hiyo ndiyo model. Kisha "prediction": a * 10 + b kwa mwanafunzi aliyesoma masaa 10.

  • Hii ni ML kwa maana kamili (supervised learning, regression) — ila ni ndogo sana. Models kubwa (kama zile za ChatGPT) zina mabilioni ya namba badala ya mbili, lakini wazo ni lilelile: rekebisha namba ili makosa kwenye data yawe madogo.
  • Tahadhari ya kufundisha: kutabiri nje ya data (mfano masaa 30 → alama 229!) ni hatari — model haijui kwamba alama haizidi 100. Hili ni somo zuri kuhusu mipaka ya models.
  • Hiari: np.corrcoef(x, y) — namba kati ya -1 na 1 inayoonyesha nguvu ya uhusiano wa mstari.

Wiki ijayo (Wiki 13) mwanafunzi atatumia scikit-learn, inayofanya haya na zaidi; leo ni kuonja tu.

Sema hivi kwa mwanafunzi

"Table ni kama kusoma ripoti ya hali ya hewa kwa namba; chati ni kama kuangalia ramani ya mawingu — unaelewa mara moja."

"fig ni ubao mzima, ax ni sehemu ya ubao unayochorea. Unaweza kugawa ubao mmoja katika sehemu mbili (subplots)."

"Fikiria wanafunzi 8. Kadri wanavyosoma masaa mengi, alama zinapanda. Tukichora mstari unaopita katikati ya pointi zao, tunaweza kubahatisha alama ya mwanafunzi wa tisa. Kuchora mstari huo kwa hesabu ndiko 'kufundisha model'. Namba mbili tulizopata ndizo 'model' yenyewe."

"Lakini model hii haijui kwamba alama haizidi 100 — ukiipa masaa 30 itasema 229! Models zinajua tu kile data ilichowafundisha. Kumbuka hili maisha yako yote ya AI."

Andika code hii live (share screen)

Notebook mpya kipindi3_matplotlib.ipynb. Hakikisha mauzo_safi.csv (ya Kipindi 2) iko kwenye folda hii.

Hatua 1 — Maandalizi.

python
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.read_csv("mauzo_safi.csv", parse_dates=["tarehe"])
df.head(3)

parse_dates inaigeuza tarehe kuwa tarehe moja kwa moja (kama pd.to_datetime).

Hatua 2 — Line plot.

python
kwa_siku = df.groupby("tarehe")["jumla"].sum()

fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(kwa_siku.index, kwa_siku.values, marker="o")
ax.set_title("Mauzo ya jumla kwa siku")
ax.set_xlabel("Tarehe")
ax.set_ylabel("Mauzo (TSh)")
ax.grid(True)
fig.autofmt_xdate()          # inazungusha tarehe zisigongane
fig.savefig("mauzo_kwa_siku.png", dpi=120, bbox_inches="tight")

Matokeo: mstari wenye pointi 5 — juu tarehe 6 na 8, chini tarehe 7. Onyesha faili mauzo_kwa_siku.png kwenye Explorer. Uliza: "Ni siku gani mauzo yalishuka? Kwa nini unadhani?"

Hatua 3 — Bar plot (mlalo, imepangwa).

python
kwa_mkoa = df.groupby("mkoa")["jumla"].sum().sort_values()

fig, ax = plt.subplots(figsize=(7, 4))
ax.barh(kwa_mkoa.index, kwa_mkoa.values, color="tab:green")
ax.set_title("Mauzo kwa mkoa")
ax.set_xlabel("Mauzo (TSh)")

Matokeo: Dar es Salaam juu (149,900), Haijulikani chini (25,000). Sema: "Kupanga (sort_values) kunafanya chati isomeke mara moja."

Hatua 4 — Histogram.

python
fig, ax = plt.subplots()
ax.hist(df["idadi"], bins=5, edgecolor="black")
ax.set_title("Mgawanyo wa idadi kwa muamala")
ax.set_xlabel("Idadi")
ax.set_ylabel("Miamala mingapi")

Eleza: "Miamala mingi iko kati ya 7 na 20; michache iko juu zaidi, na mmoja (Kalamu 40) uko mbali na wengine — huyo ni 'outlier'."

Hatua 5 — Scatter.

python
fig, ax = plt.subplots()
ax.scatter(df["bei_moja"], df["idadi"])
ax.set_title("Bei dhidi ya idadi")
ax.set_xlabel("Bei ya kipande (TSh)")
ax.set_ylabel("Idadi iliyouzwa")

Uliza: "Unaona uhusiano? Bidhaa za bei nafuu (Kalamu, Daftari) zinauzwa kwa wingi zaidi."

Hatua 6 — pandas .plot na subplots mbili.

python
ax = df.groupby("aina")["jumla"].sum().plot(kind="bar", title="Mauzo kwa aina", rot=0)
ax.set_ylabel("TSh")
python
kwa_aina = df.groupby("aina")["jumla"].sum()

fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].bar(kwa_mkoa.index, kwa_mkoa.values)
axes[0].set_title("Kwa mkoa")
axes[0].tick_params(axis="x", rotation=45)

axes[1].pie(kwa_aina.values, labels=kwa_aina.index, autopct="%1.0f%%")
axes[1].set_title("Sehemu ya kila aina")

fig.tight_layout()
fig.savefig("ripoti.png", dpi=120)

Pie: Chakula 63%, Shule 23%, Usafi 14%.

Hatua 7 — "ML ndogo": kutabiri alama. Cell ya Markdown kwanza:

markdown
## Model yetu ya kwanza
Swali: Mwanafunzi akisoma masaa X kwa wiki, atapata alama ngapi?
- Feature: masaa
- Label: alama
python
masaa = np.array([1, 2, 3, 4, 5, 6, 7, 8])
alama = np.array([35, 42, 50, 55, 61, 70, 74, 83])

# "TRAINING": tafuta mstari bora  alama = a * masaa + b
a, b = np.polyfit(masaa, alama, 1)
print(f"Model: alama = {a:.2f} x masaa + {b:.2f}")
print("Uhusiano (correlation):", np.corrcoef(masaa, alama)[0, 1].round(3))

# "PREDICTION"
for m in [2.5, 10]:
    print(f"Masaa {m} -> alama inayotarajiwa {a * m + b:.1f}")

Output:

text
Model: alama = 6.69 x masaa + 28.64
Uhusiano (correlation): 0.998
Masaa 2.5 -> alama inayotarajiwa 45.4
Masaa 10 -> alama inayotarajiwa 95.5
python
x_mstari = np.linspace(0, 10, 50)
fig, ax = plt.subplots()
ax.scatter(masaa, alama, label="Data halisi")
ax.plot(x_mstari, a * x_mstari + b, color="red", label="Model (mstari)")
ax.scatter([10], [a * 10 + b], color="orange", s=100, marker="*", label="Utabiri: masaa 10")
ax.set_xlabel("Masaa ya kusoma kwa wiki")
ax.set_ylabel("Alama")
ax.set_title("Model ya kwanza: Linear Regression")
ax.legend()

Kisha uliza: "Masaa 30?" → a * 30 + b = 229.3. "Je, inawezekana?" → Hapana! Model haijui mipaka. Somo: usiamini model nje ya data iliyofundishwa nayo.

Funga mwezi: "Mwezi huu umejenga API (FastAPI) na umeanza data (NumPy/pandas/matplotlib). Wiki ijayo tunaanza Mwezi 4 na Machine Learning kwa scikit-learn: tutafundisha models halisi kutoka data kama hii."

Maswali ya kumuuliza mwanafunzi

  1. Ungetumia chati gani kuonyesha mauzo ya kila mwezi kwa mwaka mzima? — Line.
  2. Kulinganisha idadi ya wanafunzi kwa kila shule 10? — Bar (au barh).
  3. Kuona umri wa wateja 1000 umesambaaje? — Histogram.
  4. fig na ax ni nini? — fig ni picha nzima; ax ni chati moja ndani yake.
  5. Kwenye np.polyfit(masaa, alama, 1), "training" iko wapi na "model" ni nini? — Training ni polyfit kutafuta a na b; model ni namba hizo mbili (mstari).
  6. Kwa nini utabiri wa masaa 30 hauaminiki? — Uko nje ya data iliyotumika kufundisha; model haijui alama haizidi 100.
  7. Kwa nini tunatumia savefig kabla ya kuonyesha? — Kuhifadhi picha kwa ajili ya ripoti; (kwenye script, plt.show() baada ya savefig, kwa sababu baada ya show figure inaweza kuwa tupu).

Makosa ya kawaida

Kosa Ujumbe / dalili Suluhisho
matplotlib haijasakinishwa kwenye kernel ModuleNotFoundError: No module named 'matplotlib' pip install matplotlib ndani ya .venv; restart kernel
Kwenye .py script chati haionekani Script inaisha bila dirisha Ongeza plt.show() mwishoni
savefig baada ya plt.show() kwenye script Picha nyeupe tupu savefig kwanza, show baadaye
x na y urefu tofauti ValueError: x and y must have same first dimension, but have shapes (5,) and (4,) Hakikisha zinatoka kwenye data ileile
Majina ya mhimili yanagongana Maandishi yamebanana fig.autofmt_xdate(), tick_params(rotation=45), au barh
ax.title("...") TypeError: 'Text' object is not callable ax.set_title("...") (na set_xlabel, set_ylabel)
plt.title vs ax.set_title kuchanganywa kwenye subplots Title inaenda kwenye chati isiyo sahihi Kwenye fig, axes, tumia axes[i].set_title(...)
parse_dates imesahaulika Tarehe zinapangwa kama maandishi; mhimili unasongamana pd.read_csv(..., parse_dates=["tarehe"])

Zoezi darasani

Zoezi 3.1 — Chora bar chart ya idadi (si jumla) iliyouzwa kwa kila bidhaa, imepangwa kutoka kubwa hadi ndogo, yenye title na labels. Hifadhi kama bidhaa.png.

Zoezi 3.2 — Chora line plot ya mauzo kwa siku, lakini mistari miwili kwenye chati moja: "Chakula" na "Shule" (dokezo: chuja kwanza, groupby("tarehe") kwa kila moja, label=, ax.legend()).

Zoezi 3.3 — Data ya bei ya mahindi (TSh kwa kilo) kwa miezi 6: miezi = [1, 2, 3, 4, 5, 6], bei = [700, 750, 780, 820, 870, 900]. Fundisha model ya mstari, tabiri mwezi 7 na 8, na chora data + mstari + utabiri.

Jibu

3.1

python
kwa_bidhaa = df.groupby("bidhaa")["idadi"].sum().sort_values(ascending=False)
fig, ax = plt.subplots()
ax.bar(kwa_bidhaa.index, kwa_bidhaa.values, color="tab:blue")
ax.set_title("Idadi iliyouzwa kwa bidhaa")
ax.set_xlabel("Bidhaa")
ax.set_ylabel("Idadi")
fig.savefig("bidhaa.png", dpi=120, bbox_inches="tight")

Mpangilio wa nguzo: Daftari 67, Kalamu 54, Mchele 46, Sukari 43, Sabuni 38.

3.2

python
fig, ax = plt.subplots(figsize=(8, 4))
for aina in ["Chakula", "Shule"]:
    sehemu = df[df["aina"] == aina].groupby("tarehe")["jumla"].sum()
    ax.plot(sehemu.index, sehemu.values, marker="o", label=aina)
ax.set_title("Mauzo kwa siku: Chakula dhidi ya Shule")
ax.set_ylabel("TSh")
ax.legend()
fig.autofmt_xdate()

3.3

python
miezi = np.array([1, 2, 3, 4, 5, 6])
bei = np.array([700, 750, 780, 820, 870, 900])

a, b = np.polyfit(miezi, bei, 1)
print(f"bei = {a:.1f} x mwezi + {b:.1f}")          # bei = 40.0 x mwezi + 663.3
for m in [7, 8]:
    print(f"Mwezi {m}: TSh {a * m + b:.0f}")        # Mwezi 7: TSh 943 ; Mwezi 8: TSh 983

x = np.linspace(1, 8, 50)
fig, ax = plt.subplots()
ax.scatter(miezi, bei, label="Bei halisi")
ax.plot(x, a * x + b, color="red", label="Model")
ax.scatter([7, 8], [a * 7 + b, a * 8 + b], color="orange", marker="*", s=120, label="Utabiri")
ax.set_xlabel("Mwezi")
ax.set_ylabel("TSh kwa kilo")
ax.set_title("Bei ya mahindi")
ax.legend()

Kazi ya Nyumbani

Kuwasilisha: kipindi kijacho.

"Uchambuzi wa Matokeo ya Wanafunzi." Cell ya kwanza iandike CSV hii kwa %%writefile wanafunzi.csv:

text
jina,jinsia,shule,hisabati,kiingereza,sayansi,masaa_ya_kusoma
Amina,F,Azania,78,85,80,10
Baraka,M,Azania,55,60,,6
Neema,F,Jangwani,92,88,95,14
Juma,M,Jangwani,40,52,45,3
Zawadi,F,Azania,66,,70,8
Hassani,M,Kibasila,71,65,68,9
Rehema,F,Kibasila,85,90,82,12
Faraji,M,Kibasila,35,45,40,2
Mwanaidi,F,Jangwani,59,70,62,7
Omari,M,Azania,88,75,91,13
Omari,M,Azania,88,75,91,13

Kazi:

  1. Soma, onyesha shape, info(), na idadi ya NaN kwa kila column.
  2. Ondoa duplicates. Jaza alama zinazokosekana kwa wastani wa somo hilo (ulioviringishwa kuwa namba nzima).
  3. Ongeza column wastani (wastani wa masomo 3, desimali 1) na daraja: A (≥80), B (≥65), C (≥50), F (<50).
  4. Wastani wa wastani kwa kila shule na kwa kila jinsia.
  5. Wanafunzi 3 bora (jina na wastani).
  6. Chati 3: bar ya wastani kwa shule; histogram ya wastani; scatter ya masaa_ya_kusoma dhidi ya wastani.
  7. Fundisha model ya mstari (np.polyfit) ya masaa → wastani; tabiri kwa masaa 5 na 11; chora mstari kwenye scatter.
  8. Markdown cell mwishoni: hitimisho la sentensi 3–4.
Jibu
python
# Cell 1
%%writefile wanafunzi.csv
jina,jinsia,shule,hisabati,kiingereza,sayansi,masaa_ya_kusoma
Amina,F,Azania,78,85,80,10
Baraka,M,Azania,55,60,,6
Neema,F,Jangwani,92,88,95,14
Juma,M,Jangwani,40,52,45,3
Zawadi,F,Azania,66,,70,8
Hassani,M,Kibasila,71,65,68,9
Rehema,F,Kibasila,85,90,82,12
Faraji,M,Kibasila,35,45,40,2
Mwanaidi,F,Jangwani,59,70,62,7
Omari,M,Azania,88,75,91,13
Omari,M,Azania,88,75,91,13
python
# Cell 2 — 1
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.read_csv("wanafunzi.csv")
print(df.shape)            # (11, 7)
df.info()
df.isna().sum()            # kiingereza 1, sayansi 1
python
# Cell 3 — 2
df = df.drop_duplicates()                       # (10, 7)
masomo = ["hisabati", "kiingereza", "sayansi"]
for somo in masomo:
    df[somo] = df[somo].fillna(round(df[somo].mean()))
df[masomo] = df[masomo].astype(int)
df.isna().sum().sum()                           # 0

(Kiingereza ya Zawadi = wastani wa wengine 9 = 70; Sayansi ya Baraka = 70.)

python
# Cell 4 — 3
df["wastani"] = df[masomo].mean(axis=1).round(1)

def daraja(w: float) -> str:
    if w >= 80:
        return "A"
    if w >= 65:
        return "B"
    if w >= 50:
        return "C"
    return "F"

df["daraja"] = df["wastani"].apply(daraja)
df[["jina", "wastani", "daraja"]]

Output:

text
       jina  wastani daraja
0     Amina     81.0      A
1    Baraka     61.7      C
2     Neema     91.7      A
3      Juma     45.7      F
4    Zawadi     68.7      B
5   Hassani     68.0      B
6    Rehema     85.7      A
7    Faraji     40.0      F
8  Mwanaidi     63.7      C
9     Omari     84.7      A
python
# Cell 5 — 4 na 5
print(df.groupby("shule")["wastani"].mean().round(1))
print(df.groupby("jinsia")["wastani"].mean().round(1))
df.nlargest(3, "wastani")[["jina", "wastani"]]

Output:

text
shule
Azania      74.0
Jangwani    67.0
Kibasila    64.6
Name: wastani, dtype: float64
jinsia
F    78.2
M    60.0
Name: wastani, dtype: float64
     jina  wastani
2   Neema     91.7
6  Rehema     85.7
9   Omari     84.7
python
# Cell 6 — 6
fig, axes = plt.subplots(1, 3, figsize=(15, 4))

kwa_shule = df.groupby("shule")["wastani"].mean().sort_values(ascending=False)
axes[0].bar(kwa_shule.index, kwa_shule.values, color="tab:purple")
axes[0].set_title("Wastani kwa shule")
axes[0].set_ylabel("Wastani")

axes[1].hist(df["wastani"], bins=5, edgecolor="black")
axes[1].set_title("Mgawanyo wa wastani")
axes[1].set_xlabel("Wastani")

axes[2].scatter(df["masaa_ya_kusoma"], df["wastani"])
axes[2].set_title("Masaa dhidi ya wastani")
axes[2].set_xlabel("Masaa ya kusoma")
axes[2].set_ylabel("Wastani")

fig.tight_layout()
fig.savefig("chati_wanafunzi.png", dpi=120)
python
# Cell 7 — 7
x = df["masaa_ya_kusoma"].to_numpy()
y = df["wastani"].to_numpy()
a, b = np.polyfit(x, y, 1)
print(f"wastani = {a:.2f} x masaa + {b:.2f}")
for m in [5, 11]:
    print(f"Masaa {m}: wastani unaotarajiwa {a * m + b:.1f}")

xs = np.linspace(x.min(), x.max(), 50)
fig, ax = plt.subplots()
ax.scatter(x, y, label="Wanafunzi")
ax.plot(xs, a * xs + b, color="red", label="Model")
ax.set_xlabel("Masaa ya kusoma")
ax.set_ylabel("Wastani")
ax.legend()

Output:

text
wastani = 4.20 x masaa + 33.83
Masaa 5: wastani unaotarajiwa 54.8
Masaa 11: wastani unaotarajiwa 80.0

Cell 8 — Hitimisho (mfano): Azania ina wastani wa juu zaidi (74.0). Wasichana wana wastani wa juu kuliko wavulana kwenye sampuli hii ndogo (78.2 dhidi ya 60.0). Kuna uhusiano mkubwa kati ya masaa ya kusoma na wastani — kila saa ya ziada inaongeza takriban alama 4. Sampuli ni ndogo (wanafunzi 10), hivyo hitimisho hizi si za uhakika kwa shule nzima.


Ukiulizwa swali usilolijua

Data science ni pana sana — hakuna anayejua kila function. Sema: "Sikumbuki jina la function hiyo — tuitafute", kisha tafuta kwa Kiingereza: "pandas how to ...", "matplotlib rotate x labels", "numpy difference axis 0 axis 1". Kwenye notebook unaweza pia kuandika df.groupby? au help(pd.read_csv) kuona maelezo. Vyanzo rasmi: NumPy https://numpy.org/doc/stable/ · pandas https://pandas.pydata.org/docs/ · matplotlib https://matplotlib.org/stable/ · VS Code Jupyter https://code.visualstudio.com/docs/datascience/jupyter-notebooks · Google ML Crash Course https://developers.google.com/machine-learning/crash-course


Checklist ya mwisho wa wiki

  • Anaeleza AI, ML, data, features, label, training, model, prediction kwa mfano wake
  • Anaunda notebook, kuchagua kernel ya .venv, kutumia Markdown, kurestart na Run All
  • Anaunda NumPy arrays na kusoma shape, dtype, ndim
  • Anatumia vectorized operations na boolean masks (a[a > x], &, |)
  • Anaelewa axis=0 na axis=1
  • Anasoma CSV kwa pd.read_csv na kuchunguza kwa head, info, describe, value_counts
  • Anatofautisha df["a"] / df[["a"]] na loc / iloc
  • Anachuja kwa masharti mengi na isin
  • Anasafisha data: isna, fillna, dropna, drop_duplicates, astype, to_datetime — na anakumbuka df = ...
  • Anatumia groupby + sum/mean/count/agg
  • Anachora line, bar, histogram, scatter zenye title na labels, na savefig
  • Ametumia np.polyfit kufundisha model ndogo na kueleza kwa nini kutabiri nje ya data ni hatari
  • Kazi ya nyumbani iko GitHub na outputs za notebook zinaonekana