Szybki quiz – przypomnienie poprzedniej lekcji
Temat: SQLite3 w Pythonie
Pytanie 1. Do czego służy kursor (cursor) i dlaczego nie wystarczy samo połączenie (conn)?
Pytanie 2. Co jest nie tak w tym kodzie?
cursor.execute('INSERT INTO produkty (nazwa, cena) VALUES (?, ?)', 'Laptop', 3500)
Pytanie 3. Co zostanie zapisane w bazie po wykonaniu tego kodu?
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO produkty (nazwa, cena) VALUES (?, ?)', ('Mysz', 50))
conn.close()
Pytanie 4. Dlaczego w zapytaniu jest przecinek po 30?
cursor.execute('SELECT * FROM pracownicy WHERE wiek > ?', (30,))
Pytanie 5. Wstaw brakującą metodę, aby dodać wszystkie rekordy z listy dane jednym poleceniem:
cursor.______('INSERT INTO pracownicy (imie, wiek) VALUES (?, ?)', dane)
Pytanie 6. Tabela users ma kolumnę email TEXT UNIQUE NOT NULL. Co się stanie, gdy dwa razy wstawisz ten sam e-mail, a kod jest w bloku try z except sqlite3.IntegrityError?
Pytanie 7. Po ustawieniu conn.row_factory = sqlite3.Row jak odwołasz się do wartości z kolumny nazwa w wierszu row?
Odpowiedzi
- Kursor jest „pośrednikiem”, który wykonuje polecenia SQL (
execute) i zwraca wyniki (fetchone,fetchall). Połączenie tylko otwiera dostęp do pliku bazy. - Parametry muszą być przekazane jako jedna krotka:
('Laptop', 3500). Kod przekazuje je jako dwa osobne argumenty, więc wystąpi błąd. - Nic nie zostanie zapisane. Brakuje
conn.commit()przedconn.close(), więc zmiana nie została zatwierdzona. (30,)to krotka jednoelementowa. Bez przecinka(30)to zwykła liczba w nawiasie, aexecuteoczekuje krotki (lub innej sekwencji) parametrów.executemany- Drugie wstawienie naruszy ograniczenie
UNIQUE. Zostanie zgłoszonysqlite3.IntegrityErrori wykona się blokexcept sqlite3.IntegrityError. - Po nazwie kolumny:
row['nazwa'](oprócz dostępu przez indeks, np.row[0]).
Analiza danych to proces przetwarzania, czyszczenia i interpretowania danych w celu wyciągnięcia użytecznych informacji. Python jest jednym z najpopularniejszych języków do analizy danych.
Format CSV
CSV (Comma-Separated Values) to prosty format przechowywania danych tabelarycznych w pliku tekstowym.
Imie,Nazwisko,Wiek,Miasto
Jan,Kowalski,25,Warszawa
Anna,Nowak,30,Kraków
Piotr,Wiśniewski,28,Gdańsk
Struktura:
- Pierwszy wiersz = nagłówki kolumn
- Kolejne wiersze = dane
- Separator (najczęściej przecinek)
Python ma wbudowany moduł csv do czytania i zapisywania plików CSV.
Odczyt pliku CSV
import csv
# Odczyt CSV jako lista list
with open('dane.csv', 'r', encoding='utf-8') as plik:
czytnik = csv.reader(plik)
# Pierwszy wiersz - nagłówki
naglowki = next(czytnik)
print(naglowki) # ['Imie', 'Nazwisko', 'Wiek', 'Miasto']
# Pozostałe wiersze - dane
for wiersz in czytnik:
print(wiersz)
# ['Jan', 'Kowalski', '25', 'Warszawa']
# ['Anna', 'Nowak', '30', 'Kraków']
Odczyt jako słownik
import csv
# DictReader - każdy wiersz jako słownik
with open('dane.csv', 'r', encoding='utf-8') as plik:
czytnik = csv.DictReader(plik)
for wiersz in czytnik:
print(wiersz)
# {'Imie': 'Jan', 'Nazwisko': 'Kowalski', 'Wiek': '25', 'Miasto': 'Warszawa'}
# Dostęp po kluczu
print(f"{wiersz['Imie']} {wiersz['Nazwisko']}, {wiersz['Wiek']} lat")
Zapis do CSV
import csv
dane = [
['Imie', 'Nazwisko', 'Wiek', 'Miasto'],
['Jan', 'Kowalski', 25, 'Warszawa'],
['Anna', 'Nowak', 30, 'Kraków'],
['Piotr', 'Wiśniewski', 28, 'Gdańsk']
]
# Zapis do CSV
with open('nowe_dane.csv', 'w', newline='', encoding='utf-8') as plik:
writer = csv.writer(plik)
writer.writerows(dane)
print("Plik zapisany!")
Ważne: newline='' zapobiega pustym liniom w Windows
Zapis słowników
import csv
dane = [
{'Imie': 'Jan', 'Nazwisko': 'Kowalski', 'Wiek': 25},
{'Imie': 'Anna', 'Nazwisko': 'Nowak', 'Wiek': 30},
{'Imie': 'Piotr', 'Nazwisko': 'Wiśniewski', 'Wiek': 28}
]
with open('slowniki.csv', 'w', newline='', encoding='utf-8') as plik:
naglowki = ['Imie', 'Nazwisko', 'Wiek']
writer = csv.DictWriter(plik, fieldnames=naglowki)
writer.writeheader() # Zapisz nagłówki
writer.writerows(dane) # Zapisz dane
print("Plik zapisany!")
Różne separatory
import csv
# CSV z średnikiem jako separator
with open('dane_sredniki.csv', 'r', encoding='utf-8') as plik:
czytnik = csv.reader(plik, delimiter=';')
for wiersz in czytnik:
print(wiersz)
# Zapis z tabulatorem
with open('dane_tab.csv', 'w', newline='', encoding='utf-8') as plik:
writer = csv.writer(plik, delimiter='\t')
writer.writerow(['Kolumna1', 'Kolumna2', 'Kolumna3'])
Pandas – profesjonalna analiza danych
Pandas to najpopularniejsza biblioteka do analizy danych w Pythonie.
Instalacja
pip install pandas
Podstawowe struktury danych
Pandas ma dwie główne struktury:
- Series – jednowymiarowa (jak lista z indeksami)
- DataFrame – dwuwymiarowa (tabela)
Series – jednowymiarowa seria
import pandas as pd
# Tworzenie Series
s = pd.Series([10, 20, 30, 40, 50])
print(s)
# 0 10
# 1 20
# 2 30
# 3 40
# 4 50
# dtype: int64
# Series z własnymi indeksami
s2 = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(s2)
# a 10
# b 20
# c 30
# Dostęp do elementów
print(s2['a']) # 10
print(s2[0]) # 10
DataFrame – tabela danych
DataFrame to główna struktura w Pandas – dwuwymiarowa tabela z kolumnami.
Tworzenie DataFrame
import pandas as pd
# Ze słownika
dane = {
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28],
'Miasto': ['Warszawa', 'Kraków', 'Gdańsk']
}
df = pd.DataFrame(dane)
print(df)
# Imie Wiek Miasto
# 0 Jan 25 Warszawa
# 1 Anna 30 Kraków
# 2 Piotr 28 Gdańsk
Z listy list – zagnieżdżone listy
import pandas as pd
dane = [
['Jan', 25, 'Warszawa'],
['Anna', 30, 'Kraków'],
['Piotr', 28, 'Gdańsk']
]
df = pd.DataFrame(dane, columns=['Imie', 'Wiek', 'Miasto'])
print(df)
Z listy słowników
import pandas as pd
dane = [
{'Imie': 'Jan', 'Wiek': 25, 'Miasto': 'Warszawa'},
{'Imie': 'Anna', 'Wiek': 30, 'Miasto': 'Kraków'},
{'Imie': 'Piotr', 'Wiek': 28, 'Miasto': 'Gdańsk'}
]
df = pd.DataFrame(dane)
print(df)
Wczytywanie danych z plików
CSV
import pandas as pd
# Wczytaj CSV
df = pd.read_csv('dane.csv')
print(df)
# Z różnymi opcjami
df = pd.read_csv('dane.csv',
encoding='utf-8', # Kodowanie
sep=';', # Separator
decimal=',', # Separator dziesiętny
thousands=' ') # Separator tysięcy
# Bez nagłówków
df = pd.read_csv('dane.csv', header=None)
# Własne nazwy kolumn
df = pd.read_csv('dane.csv', names=['Col1', 'Col2', 'Col3'])
Excel
import pandas as pd
# Wymaga: pip install openpyxl
# Wczytaj Excel
df = pd.read_excel('dane.xlsx')
# Konkretny arkusz
df = pd.read_excel('dane.xlsx', sheet_name='Arkusz1')
JSON
import pandas as pd
# Wczytaj JSON
df = pd.read_json('dane.json')
# Z różnymi orientacjami
df = pd.read_json('dane.json', orient='records')
Podstawowe operacje na DataFrame
Podgląd danych
import pandas as pd
df = pd.read_csv('dane.csv')
# Pierwsze 5 wierszy
print(df.head())
# Pierwsze n wierszy
print(df.head(10))
# Ostatnie 5 wierszy
print(df.tail())
# Informacje o DataFrame
print(df.info())
# Wyświetli: typy kolumn, liczbę niepustych wartości
# Statystyki opisowe (dla kolumn numerycznych)
print(df.describe())
# Wyświetli: count, mean, std, min, max, quartiles
# Wymiary (wiersze, kolumny)
print(df.shape) # (100, 5)
# Nazwy kolumn
print(df.columns) # Index(['Imie', 'Wiek', 'Miasto'])
# Typy danych
print(df.dtypes)
Dostęp do kolumn
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28],
'Miasto': ['Warszawa', 'Kraków', 'Gdańsk']
})
# Jedna kolumna (Series)
print(df['Imie'])
# 0 Jan
# 1 Anna
# 2 Piotr
# Lub jako atrybut
print(df.Imie)
# Wiele kolumn (DataFrame)
print(df[['Imie', 'Wiek']])
# Imie Wiek
# 0 Jan 25
# 1 Anna 30
# 2 Piotr 28
Dostęp do wierszy
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28],
'Miasto': ['Warszawa', 'Kraków', 'Gdańsk']
})
# Po indeksie liczbowym - iloc
print(df.iloc[0]) # Pierwszy wiersz
# Imie Jan
# Wiek 25
# Miasto Warszawa
print(df.iloc[0:2]) # Pierwsze dwa wiersze
# Po etykiecie indeksu - loc
df_indexed = df.set_index('Imie')
print(df_indexed.loc['Anna'])
# Wiek 30
# Miasto Kraków
# Konkretna komórka
print(df.iloc[0, 1]) # Wiersz 0, kolumna 1 → 25
print(df.loc[0, 'Wiek']) # Wiersz 0, kolumna 'Wiek' → 25
Filtrowanie danych
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr', 'Ewa'],
'Wiek': [25, 30, 28, 22],
'Miasto': ['Warszawa', 'Kraków', 'Gdańsk', 'Warszawa']
})
# Filtruj wiek > 25
starsi = df[df['Wiek'] > 25]
print(starsi)
# Imie Wiek Miasto
# 1 Anna 30 Kraków
# 2 Piotr 28 Gdańsk
# Filtruj miasto
warszawiacy = df[df['Miasto'] == 'Warszawa']
print(warszawiacy)
# Wiele warunków (& = and, | = or)
mlodzi_z_warszawy = df[(df['Wiek'] < 30) & (df['Miasto'] == 'Warszawa')]
print(mlodzi_z_warszawy)
# isin() - czy wartość w liście
krakowskie = df[df['Miasto'].isin(['Kraków', 'Gdańsk'])]
print(krakowskie)
Dodawanie i usuwanie kolumn
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28]
})
# Dodaj nową kolumnę
df['Pensja'] = [5000, 6000, 5500]
print(df)
# Imie Wiek Pensja
# 0 Jan 25 5000
# 1 Anna 30 6000
# 2 Piotr 28 5500
# Oblicz nową kolumnę z istniejącej
df['Wiek_za_10_lat'] = df['Wiek'] + 10
print(df)
# Usuń kolumnę
df = df.drop('Wiek_za_10_lat', axis=1)
# Lub in-place
df.drop('Pensja', axis=1, inplace=True)
print(df)
Sortowanie
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28],
'Pensja': [5000, 6000, 5500]
})
# Sortuj po wieku (rosnąco)
df_sorted = df.sort_values('Wiek')
print(df_sorted)
# Sortuj malejąco
df_sorted = df.sort_values('Wiek', ascending=False)
print(df_sorted)
# Sortuj po wielu kolumnach
df_sorted = df.sort_values(['Wiek', 'Pensja'], ascending=[True, False])
print(df_sorted)
# In-place
df.sort_values('Wiek', inplace=True)
Grupowanie i agregacja
import pandas as pd
df = pd.DataFrame({
'Miasto': ['Warszawa', 'Kraków', 'Warszawa', 'Gdańsk', 'Kraków'],
'Wiek': [25, 30, 28, 22, 35],
'Pensja': [5000, 6000, 5500, 4500, 6500]
})
# Grupuj po mieście i oblicz średnią
srednie = df.groupby('Miasto')['Pensja'].mean()
print(srednie)
# Miasto
# Gdańsk 4500.0
# Kraków 6250.0
# Warszawa 5250.0
# Wiele agregacji
agregacja = df.groupby('Miasto').agg({
'Wiek': 'mean',
'Pensja': ['min', 'max', 'mean']
})
print(agregacja)
# Policz wystąpienia
liczebnosc = df.groupby('Miasto').size()
print(liczebnosc)
Brakujące dane
import pandas as pd
import numpy as np
df = pd.DataFrame({
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, 7, 8],
'C': [9, 10, 11, 12]
})
# Sprawdź brakujące wartości
print(df.isnull())
# A B C
# 0 False False False
# 1 False True False
# 2 True False False
# 3 False False False
# Zlicz brakujące
print(df.isnull().sum())
# A 1
# B 1
# C 0
# Usuń wiersze z brakującymi
df_clean = df.dropna()
print(df_clean)
# Wypełnij brakujące wartością
df_filled = df.fillna(0)
print(df_filled)
# Wypełnij średnią
df['A'] = df['A'].fillna(df['A'].mean())
print(df)
Zapisywanie danych
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr'],
'Wiek': [25, 30, 28]
})
# Do CSV
df.to_csv('wynik.csv', index=False) # index=False = bez numeru wiersza
# Do Excel
df.to_excel('wynik.xlsx', index=False, sheet_name='Dane')
# Do JSON
df.to_json('wynik.json', orient='records', indent=2)
print("Pliki zapisane!")
Praktyczne przykłady
Przykład 1: Analiza sprzedaży
import pandas as pd
# Dane sprzedażowe
sprzedaz = pd.DataFrame({
'Produkt': ['Laptop', 'Mysz', 'Klawiatura', 'Laptop', 'Mysz'],
'Cena': [3000, 50, 200, 3000, 50],
'Ilosc': [2, 10, 5, 1, 15],
'Miasto': ['Warszawa', 'Kraków', 'Warszawa', 'Gdańsk', 'Kraków']
})
# Wartość sprzedaży
sprzedaz['Wartosc'] = sprzedaz['Cena'] * sprzedaz['Ilosc']
# Całkowita sprzedaż
print(f"Całkowita sprzedaż: {sprzedaz['Wartosc'].sum()} zł")
# Sprzedaż po produktach
po_produktach = sprzedaz.groupby('Produkt')['Wartosc'].sum()
print("\nSprzedaż po produktach:")
print(po_produktach)
# Najlepiej sprzedający się produkt
najlepszy = po_produktach.idxmax()
print(f"\nNajlepszy produkt: {najlepszy}")
Przykład 2: Czyszczenie danych
import pandas as pd
import numpy as np
# Dane z błędami
df = pd.DataFrame({
'Imie': ['Jan', 'ANNA', 'piotr', ' Ewa '],
'Wiek': [25, 200, -5, 30], # Błędne wartości
'Email': ['jan@test.com', 'invalid', 'piotr@test.com', 'ewa@test.com']
})
print("PRZED czyszczeniem:")
print(df)
# Normalizuj imiona
df['Imie'] = df['Imie'].str.strip().str.title()
# Popraw wiek (ustal realistyczne granice)
df.loc[(df['Wiek'] < 0) | (df['Wiek'] > 120), 'Wiek'] = np.nan
df['Wiek'] = df['Wiek'].fillna(df['Wiek'].median())
# Waliduj email (prosty sposób)
df['Email_OK'] = df['Email'].str.contains('@')
print("\nPO czyszczeniu:")
print(df)
Przykład 3: Analiza ocen uczniów
import pandas as pd
oceny = pd.DataFrame({
'Uczen': ['Jan', 'Anna', 'Piotr', 'Jan', 'Anna', 'Piotr'],
'Przedmiot': ['Matematyka', 'Matematyka', 'Matematyka',
'Polski', 'Polski', 'Polski'],
'Ocena': [4, 5, 3, 5, 4, 4]
})
# Średnia po uczniach
srednie_uczniow = oceny.groupby('Uczen')['Ocena'].mean()
print("Średnie uczniów:")
print(srednie_uczniow)
# Średnia po przedmiotach
srednie_przedmiotow = oceny.groupby('Przedmiot')['Ocena'].mean()
print("\nŚrednie przedmiotów:")
print(srednie_przedmiotow)
# Najlepszy uczeń
najlepszy = srednie_uczniow.idxmax()
print(f"\nNajlepszy uczeń: {najlepszy} (średnia: {srednie_uczniow.max():.2f})")
# Tabela przestawna
pivot = oceny.pivot_table(
values='Ocena',
index='Uczen',
columns='Przedmiot',
aggfunc='mean'
)
print("\nTabela przestawna:")
print(pivot)
Przykład 4: Łączenie danych
import pandas as pd
# Dane uczniów
uczniowie = pd.DataFrame({
'ID': [1, 2, 3],
'Imie': ['Jan', 'Anna', 'Piotr']
})
# Dane ocen
oceny = pd.DataFrame({
'ID_ucznia': [1, 1, 2, 3],
'Przedmiot': ['Matematyka', 'Polski', 'Matematyka', 'Polski'],
'Ocena': [4, 5, 5, 3]
})
# Połącz (merge) - jak JOIN w SQL
polaczone = pd.merge(uczniowie, oceny,
left_on='ID',
right_on='ID_ucznia')
print(polaczone)
# ID Imie ID_ucznia Przedmiot Ocena
# 0 1 Jan 1 Matematyka 4
# 1 1 Jan 1 Polski 5
# 2 2 Anna 2 Matematyka 5
# 3 3 Piotr 3 Polski 3
Pandas – przydatne metody
Unikalne wartości
import pandas as pd
df = pd.DataFrame({
'Miasto': ['Warszawa', 'Kraków', 'Warszawa', 'Gdańsk', 'Kraków']
})
# Unikalne wartości
print(df['Miasto'].unique())
# ['Warszawa' 'Kraków' 'Gdańsk']
# Liczba unikalnych
print(df['Miasto'].nunique()) # 3
# Zlicz wystąpienia
print(df['Miasto'].value_counts())
# Warszawa 2
# Kraków 2
# Gdańsk 1
Zastosuj funkcję
import pandas as pd
df = pd.DataFrame({
'Liczba': [1, 2, 3, 4, 5]
})
# apply() - zastosuj funkcję do każdego elementu
df['Kwadrat'] = df['Liczba'].apply(lambda x: x ** 2)
print(df)
# apply() z własną funkcją
def klasyfikuj(x):
if x < 3:
return 'Mała'
else:
return 'Duża'
df['Kategoria'] = df['Liczba'].apply(klasyfikuj)
print(df)
Zastąp wartości
import pandas as pd
df = pd.DataFrame({
'Ocena': ['A', 'B', 'C', 'A', 'B']
})
# Zamień wartości
mapping = {'A': 5, 'B': 4, 'C': 3}
df['Ocena_numeryczna'] = df['Ocena'].replace(mapping)
print(df)
Podsumowanie
Format CSV:
- Prosty format tabelaryczny
- Moduł
csvdo odczytu/zapisu csv.reader(),csv.DictReader()csv.writer(),csv.DictWriter()
Pandas – podstawy:
- Series – jednowymiarowa
- DataFrame – dwuwymiarowa tabela
pd.read_csv(),pd.read_excel(),pd.read_json()
Operacje DataFrame:
- Podgląd:
head(),tail(),info(),describe() - Dostęp:
df['kolumna'],df.iloc[],df.loc[] - Filtrowanie:
df[df['kolumna'] > wartość] - Sortowanie:
sort_values() - Grupowanie:
groupby()
Brakujące dane:
isnull(),dropna(),fillna()
Zapis:
to_csv(),to_excel(),to_json()
Zastosowania:
- Analiza sprzedaży
- Czyszczenie danych
- Raporty i statystyki
- Przygotowanie danych do wizualizacji
Ćwiczenia – CSV i Pandas
Moduł csv
- Stwórz plik CSV z danymi 5 osób (imię, nazwisko, wiek, miasto).
- Wczytaj plik CSV i wyświetl wszystkie dane.
- Wczytaj CSV jako słowniki (DictReader) i wyświetl.
- Dodaj nową osobę do istniejącego pliku CSV.
- Policz ile osób jest z konkretnego miasta.
- Znajdź najstarszą osobę w pliku CSV.
- Wyfiltruj osoby starsze niż 25 lat i zapisz do nowego CSV.
- Stwórz CSV z danymi produktów (nazwa, cena, ilość).
- Oblicz wartość magazynu (cena × ilość) i zapisz do nowego CSV.
- Wczytaj CSV z różnym separatorem (średnik).
Pandas – podstawy
- Stwórz DataFrame z danymi 3 osób (słownik).
- Stwórz DataFrame z listy list.
- Wyświetl pierwsze 3 wiersze DataFrame.
- Wyświetl ostatnie 2 wiersze DataFrame.
- Wyświetl informacje o DataFrame (info()).
- Wyświetl statystyki opisowe (describe()).
- Wyświetl nazwy kolumn DataFrame.
- Wyświetl wymiary DataFrame (shape).
- Wyświetl typy danych kolumn (dtypes).
- Stwórz Series z listy liczb.
Wczytywanie danych
- Wczytaj plik CSV do DataFrame.
- Wczytaj CSV bez nagłówków i dodaj własne.
- Wczytaj tylko pierwsze 10 wierszy z CSV.
- Wczytaj CSV z separatorem średnikowym.
- Wczytaj plik Excel do DataFrame.
Dostęp do danych
- Wyświetl pojedynczą kolumnę DataFrame.
- Wyświetl dwie wybrane kolumny DataFrame.
- Wyświetl pierwszy wiersz DataFrame (iloc).
- Wyświetl wiersze od 2 do 5 (iloc).
- Wyświetl konkretną komórkę DataFrame.
Filtrowanie
- Wyfiltruj osoby starsze niż 25 lat.
- Wyfiltruj osoby z konkretnego miasta.
- Wyfiltruj osoby młodsze niż 30 AND z Warszawy.
- Wyfiltruj osoby starsze niż 25 OR z Krakowa.
- Wyfiltruj osoby z listy miast (isin).
- Wyfiltruj wiersze gdzie pensja > 5000.
- Znajdź osoby których imię zaczyna się na 'A’.
- Wyfiltruj produkty droższe niż 100 zł.
- Znajdź zamówienia z ostatniego miesiąca.
- Wyfiltruj niepuste wartości w kolumnie.
Dodawanie i usuwanie
- Dodaj nową kolumnę do DataFrame.
- Oblicz nową kolumnę na podstawie istniejącej (np. wiek + 10).
- Usuń kolumnę z DataFrame.
- Usuń wiersz po indeksie.
- Zmień nazwę kolumny (rename).
Sortowanie
- Posortuj DataFrame po wieku (rosnąco).
- Posortuj DataFrame po imieniu (alfabetycznie).
- Posortuj DataFrame po wieku (malejąco).
- Posortuj po dwóch kolumnach (wiek, pensja).
- Posortuj indeks DataFrame.
Grupowanie i agregacja
- Zgrupuj po mieście i oblicz średni wiek.
- Zgrupuj po kategorii produktu i oblicz sumę sprzedaży.
- Policz ile osób jest w każdym mieście (size).
- Zgrupuj i oblicz min, max, mean dla pensji.
- Stwórz tabelę przestawną (pivot_table).
Brakujące dane
- Stwórz DataFrame z brakującymi wartościami (np.nan).
- Sprawdź które wiersze mają brakujące dane (isnull).
- Policz brakujące wartości w każdej kolumnie.
- Usuń wiersze z brakującymi wartościami (dropna).
- Wypełnij brakujące wartości zerem (fillna).
- Wypełnij brakujące wartości średnią kolumny.
- Usuń kolumny z więcej niż 50% braków.
- Wykryj duplikaty wierszy (duplicated).
- Usuń duplikaty (drop_duplicates).
- Zastąp wartości None średnią.
Zapisywanie
- Zapisz DataFrame do CSV bez indeksu.
- Zapisz DataFrame do Excel.
- Zapisz DataFrame do JSON.
- Zapisz tylko wybrane kolumny do CSV.
- Zapisz DataFrame z innym separatorem.
Operacje na tekście
- Zamień wszystkie imiona na wielkie litery (str.upper).
- Usuń spacje z początku i końca (str.strip).
- Sprawdź czy email zawiera '@’ (str.contains).
- Podziel kolumnę na dwie (str.split).
- Wyciągnij pierwsze 3 znaki z tekstu (str[:3]).
Unikalne wartości
- Wyświetl unikalne wartości kolumny 'Miasto’.
- Policz liczbę unikalnych miast (nunique).
- Zlicz wystąpienia każdej wartości (value_counts).
- Znajdź najczęściej występującą wartość.
- Usuń duplikaty z kolumny.
Apply i transform
- Zastosuj funkcję lambda do kolumny (apply).
- Stwórz kategorię na podstawie wieku (apply).
- Zastosuj własną funkcję do DataFrame.
- Oblicz nową kolumnę używając apply.
- Zamień wartości używając replace.
Łączenie danych
- Połącz dwa DataFrame wertykalnie (concat).
- Połącz dwa DataFrame horyzontalnie (concat axis=1).
- Wykonaj merge (inner join) dwóch DataFrame.
- Wykonaj left join.
- Wykonaj outer join.
Zadania analityczne
- Wczytaj dane sprzedażowe i oblicz całkowitą wartość sprzedaży.
- Znajdź 5 najlepiej sprzedających się produktów.
- Oblicz średnią cenę produktów w każdej kategorii.
- Stwórz raport miesięczny sprzedaży.
- Znajdź klientów którzy wydali najwięcej.
- Oblicz procent sprzedaży dla każdego produktu.
- Wyfiltruj zamówienia z ostatnich 30 dni.
- Znajdź produkty których nie ma na stanie.
- Oblicz średnią ocen dla każdego produktu.
- Stwórz ranking najlepszych sprzedawców.
Zadania kompleksowe
- Wczytaj dane uczniów i ocen, oblicz średnie, znajdź najlepszego.
- Analiza danych o pracownikach: średnia pensja, najstarszy, podział po działach.
- Dane sprzedażowe: najlepszy miesiąc, najbardziej dochodowy produkt, trend.
- Czyszczenie danych: usuń duplikaty, wypełnij braki, normalizuj tekst.
- Analiza ankiety: zlicz odpowiedzi, procenty, wykres rozkładu.
- Połącz dane z dwóch źródeł (merge) i stwórz raport.
- Analiza logów: zlicz błędy, najczęstsze typy, wykres czasowy.
- Dane finansowe: oblicz przychody, koszty, zysk netto.
- Segmentacja klientów: podziel na grupy wiekowe, oblicz statystyki.
- Time series: analiza sprzedaży w czasie, trendy, sezonowość.
PODSUMOWANIE
Dwa sposoby pracy z danymi tabelarycznymi w tej lekcji:
- moduł
csv(wbudowany) – dane wiersz po wierszu, bez instalacji, - biblioteka
pandas(trzeba zainstalować:pip install pandas) – dane jako tabela (DataFrame) z gotowymi operacjami.
CSV:
- To plik tekstowy: pierwszy wiersz to zwykle nagłówki, dalej dane rozdzielone separatorem (najczęściej przecinkiem).
csv.readerzwraca każdy wiersz jako listę,csv.DictReaderjako słownik (klucze = nagłówki).- Wartości odczytane z CSV są tekstem (
'25', nie25). Do obliczeń trzeba je przekonwertować. - Przy zapisie używaj
newline=''(bez tego w Windows mogą pojawić się puste linie) orazencoding='utf-8'. csv.DictWriterwymagafieldnames, a nagłówki zapisuje dopierowriteheader().- Gdy plik używa innego separatora (np.
;), podajdelimiter=';'.
Pandas – struktury:
Series– jednowymiarowa (kolumna z indeksem),DataFrame– dwuwymiarowa tabela.DataFramemożna utworzyć ze słownika (klucz = nazwa kolumny), z listy list (zcolumns=) lub z listy słowników.
Dostęp do danych:
df['Imie']→ jedna kolumna (Series),df[['Imie', 'Wiek']]→ kilka kolumn (DataFrame, podwójne nawiasy).iloc– po pozycji (numerze),loc– po etykiecie indeksu.
Filtrowanie:
df[df['Wiek'] > 25]– warunek zwraca maskęTrue/False, adf[maska]zostawia wiersze zTrue.- Wiele warunków:
&(i),|(lub), każdy warunek w osobnych nawiasach. Nie używamy tuand/or. isin([...])– czy wartość jest na liście.
Modyfikacje:
- Nowa kolumna:
df['Nowa'] = .... Usuwanie:df.drop('Kol', axis=1)(axis=1= kolumna). - Wiele metod (
drop,sort_values,fillna,dropna) zwraca nowyDataFrame. Zmiana oryginału wymaga przypisania wyniku (df = ...) alboinplace=True.
Grupowanie i braki danych:
groupby('Miasto')['Pensja'].mean()– najpierw grupa, potem kolumna, potem funkcja agregująca.- Braki to
NaN:isnull()(gdzie),isnull().sum()(ile w kolumnie),dropna()(usuń wiersze),fillna(...)(uzupełnij).
Typowe źródła błędów:
- brak nawiasów przy warunkach z
&/|, df['A', 'B']zamiastdf[['A', 'B']],- zapomniane
index=Falseprzyto_csv/to_excel(do pliku trafia dodatkowa kolumna z numerami wierszy), - brak przypisania wyniku (
df.fillna(0)samo nie zmieniadf), - zły separator lub kodowanie przy
read_csv(dane „w jednej kolumnie”, krzaczki zamiast polskich znaków).
Minimum, które powinno wejść w pamięć
Jeżeli masz zapamiętać tylko kilka rzeczy z tej lekcji, zapamiętaj te:
- CSV to tekst.
csv.readerdaje listy,csv.DictReaderdaje słowniki, a wszystkie wartości są napisami. - Zapis CSV:
open(..., 'w', newline='', encoding='utf-8').DictWriterpotrzebujefieldnamesiwriteheader(). import pandas as pd.Series= kolumna,DataFrame= tabela.- Jedna kolumna:
df['A']. Kilka kolumn:df[['A', 'B']](podwójne nawiasy). iloc– pozycja,loc– etykieta.- Filtrowanie:
df[df['Wiek'] > 25]. Kilka warunków:&/|i nawiasy wokół każdego warunku. groupby('kol')['inna'].mean()– grupuj, wybierz kolumnę, policz.- Braki danych:
isnull().sum(),dropna(),fillna(). - Zapis:
to_csv('plik.csv', index=False). - Metody Pandas zwykle nie zmieniają oryginału. Przypisz wynik albo użyj
inplace=True.
Ściągawka – najważniejsze polecenia i składnia
Moduł csv
| Zadanie | Składnia |
|---|---|
| Odczyt (listy) | czytnik = csv.reader(plik) |
| Pominięcie nagłówka | naglowki = next(czytnik) |
| Odczyt (słowniki) | czytnik = csv.DictReader(plik) |
| Inny separator | csv.reader(plik, delimiter=';') |
| Zapis (listy) | writer = csv.writer(plik), writer.writerow(w), writer.writerows(lista) |
| Zapis (słowniki) | writer = csv.DictWriter(plik, fieldnames=[...]), writer.writeheader(), writer.writerows(lista) |
python
import csv
with open('dane.csv', 'r', encoding='utf-8') as plik:
for wiersz in csv.DictReader(plik):
print(wiersz['Imie'])
with open('wynik.csv', 'w', newline='', encoding='utf-8') as plik:
writer = csv.writer(plik)
Tworzenie i wczytywanie
| Zadanie | Składnia |
|---|---|
| Import | import pandas as pd |
| Ze słownika | pd.DataFrame({'A': [1, 2], 'B': [3, 4]}) |
| Z listy list | pd.DataFrame(dane, columns=['A', 'B']) |
| Z listy słowników | pd.DataFrame([{'A': 1}, {'A': 2}]) |
| Series | pd.Series([10, 20], index=['a', 'b']) |
| CSV | pd.read_csv('f.csv', sep=';', decimal=',', encoding='utf-8') |
| Bez nagłówków / własne nazwy | header=None / names=[...] |
Excel (wymaga openpyxl) / JSON | pd.read_excel('f.xlsx') / pd.read_json('f.json') |
Podgląd
| Polecenie | Efekt |
|---|---|
df.head(n) / df.tail(n) | pierwsze / ostatnie n wierszy (domyślnie 5) |
df.info() | typy kolumn, liczba niepustych wartości |
df.describe() | statystyki kolumn liczbowych |
df.shape | (wiersze, kolumny) |
df.columns / df.dtypes | nazwy kolumn / typy |
Dostęp
| Polecenie | Efekt |
|---|---|
df['A'] | jedna kolumna (Series) |
df[['A', 'B']] | kilka kolumn (DataFrame) |
df.iloc[0], df.iloc[0:2], df.iloc[0, 1] | wiersz / zakres / komórka po pozycji |
df.loc[0, 'A'] | komórka po etykiecie |
df.set_index('A') | kolumna jako indeks (potem df.loc['wartość']) |
Filtrowanie
df[df['Wiek'] > 25]
df[df['Miasto'] == 'Warszawa']
df[(df['Wiek'] < 30) & (df['Miasto'] == 'Warszawa')] # i
df[(df['Wiek'] > 25) | (df['Miasto'] == 'Kraków')] # lub
df[df['Miasto'].isin(['Kraków', 'Gdańsk'])]
Kolumny, sortowanie, grupowanie
| Zadanie | Składnia |
|---|---|
| Nowa kolumna | df['C'] = df['A'] * df['B'] |
| Usunięcie kolumny | df = df.drop('C', axis=1) |
| Sortowanie rosnąco / malejąco | df.sort_values('A') / df.sort_values('A', ascending=False) |
| Suma / średnia / maksimum | df['A'].sum() / .mean() / .max() |
| Indeks maksimum | df['A'].idxmax() |
| Średnia w grupach | df.groupby('G')['A'].mean() |
| Liczebność grup | df.groupby('G').size() |
| Unikalne / liczba / zliczanie | .unique() / .nunique() / .value_counts() |
| Funkcja na kolumnie | df['A'].apply(lambda x: x ** 2) |
| Tekst | df['A'].str.strip(), .str.title(), .str.contains('@') |
| Łączenie (jak JOIN w SQL) | pd.merge(d1, d2, left_on='ID', right_on='ID_ucznia') |
Braki danych i zapis
| Zadanie | Składnia |
|---|---|
| Gdzie braki | df.isnull() |
| Ile braków w kolumnie | df.isnull().sum() |
| Usuń wiersze z brakami | df = df.dropna() |
| Uzupełnij stałą / średnią | df['A'] = df['A'].fillna(0) / df['A'].fillna(df['A'].mean()) |
| Zapis CSV / Excel / JSON | df.to_csv('w.csv', index=False) / df.to_excel('w.xlsx', index=False) / df.to_json('w.json', orient='records', indent=2) |
Quiz – sprawdź się
Pytanie 1. (teoria) Czym różni się Series od DataFrame? Którą strukturę zwraca df['Imie'], a którą df[['Imie', 'Wiek']]?
Pytanie 2. (analiza kodu) Plik dane.csv zawiera:
Imie,Wiek
Jan,25
Co się stanie po uruchomieniu kodu?
import csv
with open('dane.csv', 'r', encoding='utf-8') as plik:
czytnik = csv.reader(plik)
next(czytnik)
for wiersz in czytnik:
print(wiersz[1] + 1)
Pytanie 3. (znajdź błąd) Kod zapisuje plik, ale w pliku brakuje wiersza z nagłówkami. Co należy dodać i gdzie?
import csv
dane = [{'Imie': 'Jan', 'Wiek': 25}, {'Imie': 'Anna', 'Wiek': 30}]
with open('o.csv', 'w', newline='', encoding='utf-8') as plik:
writer = csv.DictWriter(plik, fieldnames=['Imie', 'Wiek'])
writer.writerows(dane)
Pytanie 4. (co zostanie wyświetlone) Jaki będzie wynik?
import pandas as pd
df = pd.DataFrame({
'Imie': ['Jan', 'Anna', 'Piotr', 'Ewa'],
'Wiek': [25, 30, 28, 22],
'Miasto': ['Warszawa', 'Kraków', 'Gdańsk', 'Warszawa']
})
print(df[(df['Wiek'] < 30) & (df['Miasto'] == 'Warszawa')])
Pytanie 5. (znajdź błąd) Ten kod ma wypisać osoby starsze niż 25 lat z Warszawy, ale nie działa poprawnie. Popraw go i wyjaśnij przyczynę.
print(df[df['Wiek'] > 25 & df['Miasto'] == 'Warszawa'])
Pytanie 6. (co zostanie wyświetlone) Dla df z pytania 4:
print(df.iloc[1, 0])
print(df.loc[2, 'Wiek'])
Pytanie 7. (wybór poprawnej składni) Która instrukcja wyświetli dwie kolumny: Imie i Wiek?
- a)
print(df['Imie', 'Wiek']) - b)
print(df[['Imie', 'Wiek']]) - c)
print(df('Imie', 'Wiek')) - d)
print(df.Imie, Wiek)
Pytanie 8. (co zostanie wyświetlone)
g = pd.DataFrame({'M': ['a', 'b', 'a'], 'P': [10, 20, 30]})
print(g.groupby('M')['P'].mean())
Pytanie 9. (przewidywanie działania)
import numpy as np
d = pd.DataFrame({'A': [1, np.nan, 3]})
d['A'].fillna(0)
print(d['A'].tolist())
d['A'] = d['A'].fillna(d['A'].mean())
print(d['A'].tolist())
Pytanie 10. (uzupełnij kod) Wstaw brakujące argumenty:
# plik używa średników jako separatora, a liczby mają przecinek dziesiętny (np. 12,5)
df = pd.read_csv('dane.csv', ______, ______)
# zapis bez dodatkowej kolumny z numerami wierszy
df.to_csv('wynik.csv', ______)
Pytanie 11. (teoria) Do jakiego polecenia SQL z poprzedniej lekcji jest podobna funkcja pd.merge()?
Pytanie 12. (zadanie praktyczne) Dany jest DataFrame o nazwie sprzedaz z kolumnami Produkt, Cena, Ilosc. Napisz kod, który:
- doda kolumnę
Wartosc(cena razy ilość), - wypisze łączną wartość sprzedaży,
- wypisze wartość sprzedaży dla każdego produktu.
Odpowiedzi
Seriesjest jednowymiarowa (jak lista z indeksem),DataFrameto dwuwymiarowa tabela.df['Imie']zwracaSeries, adf[['Imie', 'Wiek']]zwracaDataFrame.- Wystąpi błąd
TypeError.wiersz[1]to napis'25', a napisu nie można dodać do liczby1. Trzeba użyćint(wiersz[1]) + 1. - Przed
writer.writerows(dane)należy dodaćwriter.writeheader(). - Wynik:
Imie Wiek Miasto
0 Jan 25 Warszawa
3 Ewa 22 Warszawa
Zostają wiersze z indeksami 0 i 3, bo spełniają oba warunki. Indeksy oryginalnej tabeli nie są renumerowane.
5. Poprawnie: print(df[(df['Wiek'] > 25) & (df['Miasto'] == 'Warszawa')]). Operator & ma wyższy priorytet niż > i ==, więc bez nawiasów zostaje obliczone najpierw 25 & df['Miasto'], co daje błąd.
6. Anna (wiersz o pozycji 1, kolumna o pozycji 0) oraz 28 (wiersz o etykiecie 2, kolumna Wiek).
7. b
8. Wynik:
M
a 20.0
b 20.0
Name: P, dtype: float64
Dla a średnia z 10 i 30 to 20, a dla b jest tylko 20.
9. Wynik: [1.0, nan, 3.0], a potem [1.0, 2.0, 3.0]. Pierwsze fillna(0) nie zostało nigdzie przypisane, więc kolumna się nie zmieniła. Drugie zostało przypisane do d['A'] i brak zastąpiła średnia z 1 i 3, czyli 2.0.
10. pd.read_csv('dane.csv', sep=';', decimal=',') oraz df.to_csv('wynik.csv', index=False).
11. Do JOIN (łączenie tabel po wspólnej kolumnie, np. ID ucznia).
12. Przykładowe rozwiązanie:
sprzedaz['Wartosc'] = sprzedaz['Cena'] * sprzedaz['Ilosc']
print(sprzedaz['Wartosc'].sum())
print(sprzedaz.groupby('Produkt')['Wartosc'].sum())