Məzmuna keç
Educora
Universitet25 dəq31 / 42

pandas-ın əsasları: Series və DataFrame

Cədvəl verilənləri ilə pandas-da işlə: Series və DataFrame, CSV-nin oxunması, `head`, `info`, `describe`, `loc` və `iloc` ilə seçmə, süzgəc, çeşidləmə və yeni sütunlar.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Series və DataFrame-in quruluşunu (qiymətlər, indeks, sütunlar, tiplər) izah etmək
  • CSV-ni oxuyub head, info, describe və value_counts ilə verilənlərə ilk baxış keçirmək
  • loc, iloc, maskalar və query ilə sətir və sütunları seçmək, çeşidləmək
  • Yeni sütunları vektorlaşdırılmış şəkildə və zəncirvari mənimsətmə xətası olmadan yaratmaq

Aysel kiçik onlayn dəftərxana mağazası işlədir. Satışlar Excel cədvəlindədir: məhsul, kateqoriya, qiymət, anbar qalığı, satılan say. Yüzlərlə sətirdə «hansı kateqoriya ən çox gəlir gətirir?» və ya «nəyi yenidən sifariş etmək lazımdır?» suallarına cavab tapmaq üçün pandas kitabxanası yaradılıb. O, NumPy massivlərinin üzərinə sütun adları, sətir etiketləri və cədvəllər üçün yüzlərlə hazır əməliyyat əlavə edir.

Series və DataFrame

Tərif
Series

Etiketli birölçülü massiv: qiymətlər (NumPy massivi) və onlara uyğun indeks (etiketlər). Adı (name) və tipi (dtype) var.

Tərif
DataFrame

İkiölçülü cədvəl: ortaq indeksi paylaşan Series-lərin (sütunların) toplusu. Hər sütunun öz tipi ola bilər — mətn, tam ədəd, kəsr, tarix.

Series-də elementə həm etiketlə (s['Pen']), həm də mövqe ilə (s.iloc[0]) müraciət etmək olar. Hesab əməlləri NumPy-dakı kimi vektorlaşdırılıb. Aşağıda qiymətlərə 18% ƏDV əlavə edirik:

Python
import pandas as pd

prices = pd.Series([1.5, 0.6, 35.0, 49.9],
                   index=['Notebook', 'Pen', 'Backpack', 'Headphones'],
                   name='price')
print(prices)
print(prices['Pen'], prices.iloc[-1])
print(prices[prices > 10].index.tolist())
print((prices * 1.18).round(2).tolist())
▸ Gözlənilən nəticə
Notebook       1.5
Pen            0.6
Backpack      35.0
Headphones    49.9
Name: price, dtype: float64
0.6 49.9
['Backpack', 'Headphones']
[1.77, 0.71, 41.3, 58.88]

DataFrame-i ən sadə yolla lüğətdən qururuq: açarlar sütun adları, qiymətlər isə sütunların məzmunudur. shape (sətirlər, sütunlar) korteji, dtypes isə hər sütunun tipini göstərir. pandas 3-də mətn sütunlarının tipi str-dir (köhnə versiyalarda object görəcəksən).

Python
import pandas as pd

df = pd.DataFrame({
    'name': ['Aysel', 'Murad', 'Leyla'],
    'age': [19, 21, 20],
    'city': ['Baku', 'Ganja', 'Baku'],
})
print(df)
print(df.shape, df.columns.tolist())
print(df.dtypes)
▸ Gözlənilən nəticə
    name  age   city
0  Aysel   19   Baku
1  Murad   21  Ganja
2  Leyla   20   Baku
(3, 3) ['name', 'age', 'city']
name      str
age     int64
city      str
dtype: object

CSV-ni oxumaq və verilənlərə ilk baxış

Real işdə cədvəl fayldan oxunur: pd.read_csv('sales.csv'). Brauzerdə fayl olmadığı üçün mətni io.StringIO ilə «fayla» çeviririk — read_csv üçün fərqi yoxdur. Hər kod bloku ayrıca işlədiyindən cədvəli hər blokda yenidən yaradırıq. İlk addım həmişə eynidir: head() ilk sətirləri, info() sütunları, tipləri və boş olmayan qiymətlərin sayını göstərir. Aşağıda eyni məlumatı hissə-hissə çap edirik: shape, dtypes və count().

Python
import io
import pandas as pd

data = '''product,category,price,stock,sold
Notebook,Stationery,1.5,120,340
Pen,Stationery,0.6,300,820
Backpack,Accessories,35.0,25,48
Headphones,Electronics,49.9,15,37
USB cable,Electronics,6.5,80,150
Mug,Home,8.0,40,95
Desk lamp,Home,27.5,12,20'''
df = pd.read_csv(io.StringIO(data))
print(df.head(3))
print(df.shape)
print(df.dtypes)
print(df.count().tolist())
▸ Gözlənilən nəticə
    product     category  price  stock  sold
0  Notebook   Stationery    1.5    120   340
1       Pen   Stationery    0.6    300   820
2  Backpack  Accessories   35.0     25    48
(7, 5)
product         str
category        str
price       float64
stock         int64
sold          int64
dtype: object
[7, 7, 7, 7, 7]
read_csv tipləri özü təyin edib: ədədlər int64 və float64, mətn str. count() hər sütunda boş olmayan qiymətləri sayır — burada boşluq yoxdur.

describe() hər ədədi sütun üçün say, orta, standart meyl (n − 1-ə bölməklə), minimum, kvartillər və maksimumu bir cədvəldə verir. Kateqoriyalı sütun üçün isə value_counts() hər qiymətə neçə dəfə rast gəlindiyini sayır.

Python
import io
import pandas as pd

data = '''product,category,price,stock,sold
Notebook,Stationery,1.5,120,340
Pen,Stationery,0.6,300,820
Backpack,Accessories,35.0,25,48
Headphones,Electronics,49.9,15,37
USB cable,Electronics,6.5,80,150
Mug,Home,8.0,40,95
Desk lamp,Home,27.5,12,20'''
df = pd.read_csv(io.StringIO(data))
print(df.describe().round(2))
print(df['category'].value_counts())
▸ Gözlənilən nəticə
       price   stock    sold
count   7.00    7.00    7.00
mean   18.43   84.57  215.71
std    19.16  102.74  288.06
min     0.60   12.00   20.00
25%     4.00   20.00   42.50
50%     8.00   40.00   95.00
75%    31.25  100.00  245.00
max    49.90  300.00  820.00
category
Stationery     2
Electronics    2
Home           2
Accessories    1
Name: count, dtype: int64
h = (n − 1) · q Q(q) = x₍ₖ₎ + (h − k) · (x₍ₖ₊₁₎ − x₍ₖ₎), k = ⌊h⌋
burada:
  • qsəviyyə: 0,25 (birinci kvartil), 0,5 (median), 0,75 (üçüncü kvartil)
  • x₍ₖ₎artan sıra ilə düzülmüş qiymətlərdən k-cısı (0-dan saymaqla)
  • hsıralanmış verilənlərdə «kəsr mövqe»

pandas və NumPy susmaya görə kvantilləri iki qonşu qiymət arasında xətti interpolyasiya ilə hesablayır.

Nümunə 1: describe-dakı kvartilləri yoxlayaq

price sütununun 25% və 75% kvartillərini əl ilə hesabla və describe() nəticəsi ilə müqayisə et.

Həllini göstər
Sıralanmış qiymətlər: 0,6; 1,5; 6,5; 8,0; 27,5; 35,0; 49,9 (n = 7).
q = 0,25: h = 6 · 0,25 = 1,5 → x₍₁₎ = 1,5 ilə x₍₂₎ = 6,5 arasının yarısı: 1,5 + 0,5 · 5 = 4,0.
q = 0,75: h = 6 · 0,75 = 4,5 → 27,5 + 0,5 · 7,5 = 31,25.
Median: h = 3 → x₍₃₎ = 8,0. Hər üçü describe() ilə üst-üstə düşür. Orta (18,43) mediandan çox böyükdür — bir neçə baha məhsul ortanı yuxarı çəkir.

Seçmə: sütunlar, loc və iloc

YazılışNə qaytarır
df['price']bir sütun — Series
df[['product', 'price']]bir neçə sütun — DataFrame
df.loc[row_labels, col_labels]etiketlərlə seçmə; kəsikdə son etiket daxildir
df.iloc[row_pos, col_pos]mövqelərlə seçmə; kəsikdə son mövqe daxil deyil
Python
import io
import pandas as pd

data = '''product,category,price,stock,sold
Notebook,Stationery,1.5,120,340
Pen,Stationery,0.6,300,820
Backpack,Accessories,35.0,25,48
Headphones,Electronics,49.9,15,37
USB cable,Electronics,6.5,80,150
Mug,Home,8.0,40,95
Desk lamp,Home,27.5,12,20'''
df = pd.read_csv(io.StringIO(data))
print(df['price'].head(3).tolist())
print(df.loc[2, 'product'], '|', df.iloc[0, 2])
print(df.loc[1:3, 'product':'price'])
print(df.iloc[1:3, 0:2])
df = df.set_index('product')
print(df.loc['Mug', 'price'])
▸ Gözlənilən nəticə
[1.5, 0.6, 35.0]
Backpack | 1.5
      product     category  price
1         Pen   Stationery    0.6
2    Backpack  Accessories   35.0
3  Headphones  Electronics   49.9
    product     category
1       Pen   Stationery
2  Backpack  Accessories
8.0
loc[1:3] üç sətir (1, 2, 3), iloc[1:3] isə iki sətir (1, 2) qaytardı. set_index('product')-dan sonra sətirlərə məhsulun adı ilə müraciət etmək olur.

Süzgəc və çeşidləmə

Sətirləri NumPy-dakı kimi məntiqi maskalarla süzürük: şərtləri &, |, ~ ilə birləşdirib mötərizəyə alırıq. isin qiymətin siyahıda olub-olmadığını yoxlayır, query şərti mətn kimi yazmağa imkan verir. sort_values sütuna görə çeşidləyir, nlargest isə ən böyük n qiyməti birbaşa qaytarır.

Python
import io
import pandas as pd

data = '''product,category,price,stock,sold
Notebook,Stationery,1.5,120,340
Pen,Stationery,0.6,300,820
Backpack,Accessories,35.0,25,48
Headphones,Electronics,49.9,15,37
USB cable,Electronics,6.5,80,150
Mug,Home,8.0,40,95
Desk lamp,Home,27.5,12,20'''
df = pd.read_csv(io.StringIO(data))
cheap = df[df['price'] < 10]
print(cheap[['product', 'price']])
print(df[(df['category'] == 'Electronics') & (df['stock'] < 50)]['product'].tolist())
print(df[df['category'].isin(['Home', 'Accessories'])]['product'].tolist())
print(df.query('price > 20 and sold > 30')[['product', 'sold']])
print(df.sort_values('sold', ascending=False).head(3)[['product', 'sold']])
print(df.nlargest(2, 'price')[['product', 'price']])
▸ Gözlənilən nəticə
     product  price
0   Notebook    1.5
1        Pen    0.6
4  USB cable    6.5
5        Mug    8.0
['Headphones']
['Backpack', 'Mug', 'Desk lamp']
      product  sold
2    Backpack    48
3  Headphones    37
     product  sold
1        Pen   820
0   Notebook   340
4  USB cable   150
      product  price
3  Headphones   49.9
2    Backpack   35.0

Yeni sütunlar

Yeni sütun mənimsətmə ilə yaranır: df['revenue'] = df['price'] * df['sold'] — dövr yoxdur, hesablama bütün sütun üzrə gedir. Şərtli qiymət üçün np.where, yalnız bəzi sətirləri dəyişmək üçün df.loc[maska, 'sütun'] = qiymət işlədilir. rename və drop yeni DataFrame qaytarır, ona görə nəticəni dəyişənə yenidən mənimsədirik.

Python
import io
import numpy as np
import pandas as pd

data = '''product,category,price,stock,sold
Notebook,Stationery,1.5,120,340
Pen,Stationery,0.6,300,820
Backpack,Accessories,35.0,25,48
Headphones,Electronics,49.9,15,37
USB cable,Electronics,6.5,80,150
Mug,Home,8.0,40,95
Desk lamp,Home,27.5,12,20'''
df = pd.read_csv(io.StringIO(data))
df['revenue'] = (df['price'] * df['sold']).round(2)
df['band'] = np.where(df['price'] >= 20, 'high', 'low')
df['status'] = 'ok'
df.loc[df['stock'] < 20, 'status'] = 'reorder'
df = df.rename(columns={'sold': 'units'}).drop(columns=['category'])
print(df)
print(f"Total revenue: {df['revenue'].sum():.2f} AZN")
▸ Gözlənilən nəticə
      product  price  stock  units  revenue  band   status
0    Notebook    1.5    120    340    510.0   low       ok
1         Pen    0.6    300    820    492.0   low       ok
2    Backpack   35.0     25     48   1680.0  high       ok
3  Headphones   49.9     15     37   1846.3  high  reorder
4   USB cable    6.5     80    150    975.0   low       ok
5         Mug    8.0     40     95    760.0   low       ok
6   Desk lamp   27.5     12     20    550.0  high  reorder
Total revenue: 6813.30 AZN
Nümunə 2: Elektronikanın gəlirdəki payı

Yuxarıdakı cədvələ görə ümumi gəlirin neçə faizi Electronics kateqoriyasından gəlir? Əl ilə hesabla və pandas ifadəsini yaz.

Həllini göstər
Electronics: Headphones 49,9 · 37 = 1846,3 və USB cable 6,5 · 150 = 975,0; cəmi 2821,3 manat.
Ümumi gəlir 6813,3 manatdır.
Pay = 2821,3 / 6813,3 ≈ 0,414, yəni təxminən 41,4%.
pandas: df.loc[df['category'] == 'Electronics', 'revenue'].sum() / df['revenue'].sum() (bu, drop-dan əvvəl, category sütunu hələ olanda hesablanmalıdır).

pandas analitiklərin, iqtisadçıların, bank və telekom şirkətlərinin, elmi laboratoriyaların gündəlik alətidir: hesabatlar, satış analizi, sorğuların nəticələri, sensor jurnalları. Növbəti dərsdə buraxılmış qiymətlərlə, qruplaşdırma, cədvəllərin birləşdirilməsi və tarixlərlə işləyəcəyik.

Tapşırıq

CSV-ni DataFrame-ə oxu. 1) Balı 80 və ya daha çox olan tələbələrin adlarını bala görə azalan sıra ilə siyahı kimi çap et; 2) bütün tələbələrin orta balını 1 onluq rəqəmə qədər yuvarlaqlaşdırıb çap et.

Tapşırıq · Python
import io
import pandas as pd

data = '''name,group,score
Aysel,A,91
Murad,B,76
Leyla,A,85
Elvin,B,64
Nigar,A,78
Tural,B,88'''
df = pd.read_csv(io.StringIO(data))
# 1) names with score >= 80, highest first
# 2) mean score, 1 decimal
▸ Gözlənilən nəticə
['Aysel', 'Tural', 'Leyla']
80.3
Tapşırıq

Kafenin sifarişlər cədvəlinə total = price * qty sütunu əlavə et. Sonra ayrı sətirlərdə çap et: 1) total-ı ən böyük olan məhsulun adı; 2) total-ı 25-dən böyük olan məhsulların siyahısı; 3) bütün total-ların cəmi.

Tapşırıq · Python
import pandas as pd

orders = pd.DataFrame({
    'item': ['tea', 'coffee', 'cake', 'juice'],
    'price': [2.5, 4.0, 5.5, 3.0],
    'qty': [12, 7, 4, 9],
})
# add the total column, then print the three results
▸ Gözlənilən nəticə
tea
['tea', 'coffee', 'juice']
107.0

Əsas fikirlər

  • Series etiketli birölçülü massivdir, DataFrame isə ortaq indeksli Series-lərdən ibarət cədvəldir.
  • Yeni verilənlərə ilk baxış: head(), info(), describe(), value_counts().
  • loc etiketlərlə işləyir və kəsiyin sonunu daxil edir; iloc mövqelərlə işləyir və sonu daxil etmir.
  • Süzgəc üçün maskalar (&, |, ~), isin və query; çeşidləmə üçün sort_values və nlargest.
  • Sətirlərin bir hissəsini dəyişmək üçün df.loc[maska, 'sütun'] = qiymət yaz, zəncirvari mənimsətmədən qaç.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
İndeksi 0, 1, 2, … olan DataFrame üçün df.loc[2:4] neçə sətir qaytarır?