import pandas as pd
from tabulate import tabulate
random.seed(0)
start_date = datetime(2015, 1, 1).date()
end_date = datetime(2020, 12, 31).date()
def random_date(start, end):
return start + (end - start) * random.random()Przetwarzanie i analiza danych w środowisku Python
1. Wprowadzenie
Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see https://quarto.org.
2. Podstawy Pythona
Zakres: Typy danych, składnia, instalacja pakietów, podstawowe funkcje.
Kompetencje: Zrozumienie typów danych i składni pythona, umiejętność pisania prostego kodu.
Typy zmiennych
Lista (
list) jest podobna do listy w R (list()). Oba są kolekcjami, które mogą przechowywać różne typy danych.Słownik (
dict) można porównać do list w R z nazwanymi elementami lub wektorów. W R nie ma bezpośredniego odpowiednika dla słownika, ale listy lub wektory z nazwami elementów pełnią podobną rolę.Krotka w Pythonie (
tuple) jest niezmienialną sekwencją, dla której nie ma bezpośredniego odpowiednika w R.Zbiór (
set) jest podobny do zbioru w R (set), oba reprezentują kolekcję unikalnych elementów.DataFrame (
pandas.DataFrame) jest analogiczny dodata.framew R. Oba są używane do przechowywania danych tabelarycznych.Seria (
pandas.Series) jest podobna do wektora w R (vector). Obie reprezentują jednowymiarowe sekwencje danych.
| Nazwa zmiennej | Typ zmiennej | Nazwa w R |
|---|---|---|
lista |
list |
list() |
słownik |
dict |
list() lub vector |
krotka |
tuple |
- |
zbiór |
set |
set |
dataframe |
pandas.DataFrame |
data.frame |
seria |
pandas.Series |
vector |
Składnia
Składnia języka Python różni się od składni R w kilku kluczowych aspektach, co ma wpływ na sposób pisania i czytania kodu.
Wcięcia vs Nawiasy Klamrowe
Python używa wcięć (spacji lub tabulatorów) do definiowania bloków kodu. Wcięcia są kluczowe dla struktury kodu i muszą być konsekwentne. Przykład:
| Col1 | Col2 | Col3 | |
|---|---|---|---|
| Wcięcia vs Nawiasy Klamrowe | Python używa wcięć do definiowania bloków kodu. R używa nawiasów klamrowych {} do definiowania bloków kodu, podobnie jak wiele innych języków programowania. | |
|
| Indeksowanie | Python rozpoczyna indeksowanie od 0. Przykład: lista[0] oznacza pierwszy element listy. R rozpoczyna indeksowanie od 1. Przykład: lista[1] oznacza pierwszy element listy. | ||
| Przypisanie Zmiennych | Python używa operatora = do przypisania wartości do zmiennej. Przykład: x = 5 R często używa <- jako operatora przypisania, chociaż = jest również akceptowany. Przykład: x <- 5 lub x = 5 | ||
| Definicja Funkcji | Funkcje definiuje się za pomocą słowa kluczowego def, a następnie nazwy funkcji i argumentów w nawiasach. W R funkcje definiuje się za pomocą function, a argumenty umieszcza się w nawiasach. | |
|
if x > 10:
print("x jest większe niż 10")
R używa nawiasów klamrowych {} do definiowania bloków kodu, podobnie jak wiele innych języków programowania. Przykład:
```{r eval = F}
if (x > 10) { print(“x jest większe niż 10”) }
2. **Indeksowanie** Python rozpoczyna indeksowanie od 0. Przykład: lista\[0\] oznacza pierwszy element listy. R rozpoczyna indeksowanie od 1. Przykład: lista\[1\] oznacza pierwszy element listy.
3. **Przypisanie Zmiennych**
Python używa operatora = do przypisania wartości do zmiennej. Przykład: x = 5 R często używa \<- jako operatora przypisania, chociaż = jest również akceptowany. Przykład: x \<- 5 lub x = 5
4. **Definicja Funkcji**
```{def moja_funkcja(x):}
return x * 2
W R funkcje definiuje się za pomocą function, a argumenty umieszcza się w nawiasach. Przykład:
```{r eval = F}
moja_funkcja <- function(x) {
x * 2 }
**Biblioteki vs Pakiety**
W Pythonie, do importowania modułów/bibliotek używa się import. Można importować całe moduły lub poszczególne funkcje. Przykład: import numpy as np lub from math import sqrt
W R, aby używać pakietów, najpierw należy je załadować za pomocą library(). Przykład: library(ggplot2)
### Instalacja pakietów
- Funkcja `import`
- Składnia: `import nazwa_pakietu`
- Przykład użycia:
::: {.cell execution_count=1}
``` {.python .cell-code}
import random
import pandas as pd
import plotly as px
import random
from datetime import datetime
from distutils.command import install
:::
3. Przetwarzanie danych - pakiet pandas
3.1. Tworzenie zbiorów danych
2.1 Tworzenie zmiennych
Tworzenie ramki danych
n = 100
plec = ["M", "K"]
wojewodztwa = ["mazowieckie","śląskie", "wielkopolskie", "małopolskie",
"dolnośląskie", "warmińsko-mazurskie", "lubuskie", "lubelskie",
"podlaskie", "łódzkie", "zachodniopomorskie", "pomorskie",
"kujawsko-pomorskie","wielkoposlkie"]
kody_icd_10 = ["I10", "E11", "J18", "K21", "L20", "M54", "N30", "O14", "P07", "R51"]
nazwy_swiadczen = ["Badanie krwi", "USG", "RTG", "EKG", "Konsultacja specjalistyczna", "Operacja"]
dane = pd.DataFrame({
"id": range(1, n + 1),
"wiek": [random.randint(0, 100) for _ in range(n)],
"płeć": [random.choice(plec) for _ in range(n)],
"województwo": [random.choice(wojewodztwa) for _ in range(n)],
"kod ICD-10": [random.choice(kody_icd_10) for _ in range(n)],
"data": [random_date(start_date, end_date) for _ in range(n)],
"nazwa świadczenia": [random.choice(nazwy_swiadczen) for _ in range(n)],
"koszt świadczenia": [round(random.uniform(100, 1000), 2) for _ in range(n)],
"zgon": [random.choice(["tak", "nie"]) for _ in range(n)]
})
print('Początek obserwacji:', start_date)
print('Koniec obserwacji: ', end_date)Początek obserwacji: 2015-01-01
Koniec obserwacji: 2020-12-31
Selekcja danych
Wybór kolumny
kolumna = dane['wiek']
print(kolumna.to_string(index=False)) 49
97
53
5
33
65
62
51
100
38
61
45
74
27
64
17
36
17
96
12
79
32
68
90
77
18
39
12
93
9
87
42
60
71
12
45
55
40
78
81
26
70
61
56
66
33
7
70
1
11
92
51
90
100
85
80
0
78
63
42
31
93
41
90
8
24
72
28
30
18
69
57
11
10
40
65
62
13
38
70
37
90
15
70
42
69
26
77
70
75
36
56
11
76
49
40
73
30
37
23
Wybór wierszy
wiersze = dane[13:21]
print(wiersze.head().to_string(index=False)) id wiek płeć województwo kod ICD-10 data nazwa świadczenia koszt świadczenia zgon
14 27 M wielkoposlkie J18 2016-02-25 EKG 877.65 tak
15 64 M łódzkie P07 2015-09-09 EKG 392.05 nie
16 17 K wielkopolskie M54 2019-12-06 USG 327.33 tak
17 36 K pomorskie E11 2020-02-12 EKG 417.25 nie
18 17 K dolnośląskie J18 2015-03-02 Konsultacja specjalistyczna 209.24 nie
Zakres etykiet
zakres_etykieta = dane.loc[2:11,
['wiek', 'płeć']]
print(zakres_etykieta) wiek płeć
2 53 M
3 5 K
4 33 K
5 65 M
6 62 M
7 51 M
8 100 M
9 38 M
10 61 M
11 45 K
zakres_pozycja = dane.iloc[10:20, [5, 7]]
print(zakres_pozycja.head()) data koszt świadczenia
10 2020-12-29 487.98
11 2018-07-06 475.32
12 2015-12-31 546.96
13 2016-02-25 877.65
14 2015-09-09 392.05
FILTROWANIE DANYCH
Filtrowanie wyników w DataFrame w pandas jest bardzo podobne do używania funkcji filter z pakietu dplyr w R. W pandas, możesz używać warunków logicznych bezpośrednio na DataFrame do filtrowania danych. Kluczowym aspektem jest stosowanie nawiasów do grupowania warunków oraz używanie operatorów logicznych (&, |) do łączenia tych warunków.
dane.query('wiek > 20')
dane.query('wiek > 20 & id > 56')
#dane.query('płeć' == 'M')| id | wiek | płeć | województwo | kod ICD-10 | data | nazwa świadczenia | koszt świadczenia | zgon | |
|---|---|---|---|---|---|---|---|---|---|
| 57 | 58 | 78 | M | podlaskie | M54 | 2019-03-28 | Operacja | 312.99 | tak |
| 58 | 59 | 63 | K | lubelskie | N30 | 2017-10-27 | Badanie krwi | 265.55 | nie |
| 59 | 60 | 42 | M | podlaskie | P07 | 2019-10-19 | Operacja | 435.22 | nie |
| 60 | 61 | 31 | K | łódzkie | J18 | 2018-02-05 | Operacja | 696.88 | nie |
| 61 | 62 | 93 | M | kujawsko-pomorskie | L20 | 2020-06-28 | Konsultacja specjalistyczna | 874.88 | tak |
| 62 | 63 | 41 | M | mazowieckie | E11 | 2015-05-26 | RTG | 641.09 | nie |
| 63 | 64 | 90 | M | mazowieckie | O14 | 2015-10-13 | USG | 454.42 | nie |
| 65 | 66 | 24 | K | warmińsko-mazurskie | I10 | 2019-07-21 | RTG | 218.82 | nie |
| 66 | 67 | 72 | K | dolnośląskie | L20 | 2017-09-09 | Operacja | 369.45 | tak |
| 67 | 68 | 28 | M | wielkoposlkie | J18 | 2020-03-03 | Operacja | 475.07 | nie |
| 68 | 69 | 30 | M | lubelskie | P07 | 2019-10-21 | Badanie krwi | 933.76 | nie |
| 70 | 71 | 69 | M | kujawsko-pomorskie | L20 | 2017-10-06 | USG | 368.23 | nie |
| 71 | 72 | 57 | M | wielkoposlkie | N30 | 2017-03-24 | Badanie krwi | 419.11 | tak |
| 74 | 75 | 40 | K | małopolskie | N30 | 2015-03-15 | RTG | 673.34 | tak |
| 75 | 76 | 65 | K | podlaskie | E11 | 2015-07-18 | USG | 576.29 | nie |
| 76 | 77 | 62 | K | zachodniopomorskie | E11 | 2019-10-06 | EKG | 438.79 | tak |
| 78 | 79 | 38 | M | wielkoposlkie | O14 | 2018-08-07 | Operacja | 965.76 | tak |
| 79 | 80 | 70 | M | pomorskie | O14 | 2015-06-17 | Badanie krwi | 911.14 | nie |
| 80 | 81 | 37 | M | wielkopolskie | M54 | 2017-07-23 | Badanie krwi | 497.17 | nie |
| 81 | 82 | 90 | M | mazowieckie | M54 | 2019-07-12 | Badanie krwi | 434.44 | nie |
| 83 | 84 | 70 | K | zachodniopomorskie | O14 | 2020-05-28 | RTG | 181.95 | tak |
| 84 | 85 | 42 | M | lubuskie | E11 | 2017-07-04 | Badanie krwi | 266.91 | tak |
| 85 | 86 | 69 | K | warmińsko-mazurskie | O14 | 2020-10-31 | Konsultacja specjalistyczna | 197.75 | nie |
| 86 | 87 | 26 | M | mazowieckie | N30 | 2020-01-27 | Operacja | 200.94 | tak |
| 87 | 88 | 77 | M | małopolskie | I10 | 2020-10-31 | Konsultacja specjalistyczna | 644.99 | nie |
| 88 | 89 | 70 | K | mazowieckie | L20 | 2018-08-23 | Konsultacja specjalistyczna | 238.49 | tak |
| 89 | 90 | 75 | K | pomorskie | M54 | 2016-05-26 | USG | 732.34 | tak |
| 90 | 91 | 36 | K | kujawsko-pomorskie | J18 | 2020-03-09 | USG | 935.44 | tak |
| 91 | 92 | 56 | K | mazowieckie | J18 | 2015-02-14 | Badanie krwi | 266.84 | nie |
| 93 | 94 | 76 | K | zachodniopomorskie | N30 | 2019-06-11 | Konsultacja specjalistyczna | 257.26 | tak |
| 94 | 95 | 49 | M | podlaskie | E11 | 2016-10-24 | Operacja | 963.58 | tak |
| 95 | 96 | 40 | M | łódzkie | E11 | 2018-06-03 | Konsultacja specjalistyczna | 406.35 | nie |
| 96 | 97 | 73 | K | śląskie | E11 | 2016-12-29 | EKG | 571.01 | tak |
| 97 | 98 | 30 | M | małopolskie | K21 | 2017-12-17 | Konsultacja specjalistyczna | 419.83 | tak |
| 98 | 99 | 37 | K | śląskie | K21 | 2016-07-28 | RTG | 668.37 | nie |
| 99 | 100 | 23 | M | łódzkie | I10 | 2019-12-13 | Badanie krwi | 177.85 | nie |
Wiele warunków
wynik = dane[dane['wiek'] > 30]Funkcja query
# AND - oba warunki muszą być spełnione
wynik = dane[(dane['wiek'] > 30) & (dane['płeć'] == 'K')]
# OR - wystarczy, że jeden z warunków jest spełniony
wynik = dane[(dane['wiek'] > 30) | (dane['płeć'] == 'K')]Listy wartości
# Załóżmy, że chcesz wybrać wiersze, gdzie kolumna 'województwo' zawiera jedno z kilku województw
województwa = ['pomorskie', 'małopolskie', 'śląskie']
wynik = dane[dane['województwo'].isin(województwa)]GRUPOWANIE DANYCH
groupby
grupuj = pd.DataFrame(dane.groupby('płeć'))
print(grupuj)
ow = dane.groupby('województwo')
print(pd.DataFrame(ow)) 0 1
0 K id wiek płeć województwo kod ICD...
1 M id wiek płeć województwo kod IC...
0 1
0 dolnośląskie id wiek płeć województwo kod ICD-10 ...
1 kujawsko-pomorskie id wiek płeć województwo kod ICD-...
2 lubelskie id wiek płeć województwo kod ICD-10 ...
3 lubuskie id wiek płeć województwo kod ICD-10 ...
4 mazowieckie id wiek płeć województwo kod ICD-10 ...
5 małopolskie id wiek płeć województwo kod ICD-10 ...
6 podlaskie id wiek płeć województwo kod ICD-10 ...
7 pomorskie id wiek płeć województwo kod ICD-10 ...
8 warmińsko-mazurskie id wiek płeć województwo kod ICD...
9 wielkopolskie id wiek płeć województwo kod ICD-10 ...
10 wielkoposlkie id wiek płeć województwo kod ICD-10 ...
11 zachodniopomorskie id wiek płeć województwo kod ICD-...
12 łódzkie id wiek płeć województwo kod ICD-10 ...
13 śląskie id wiek płeć województwo kod ICD-10 ...
Agregacje
# Dla jednej kolumny
dane['wiek'].agg('mean')
# Wiele kolumn
dane.agg({
'wiek': 'mean',
'koszt świadczenia': 'max'
})
#Agregacja po grupowaniu
dane.groupby('płeć').agg({
'wiek': 'mean',
'koszt świadczenia': 'max'
})
#Agregacja właśną funkcją
def zakres_wiekowy(x):
return max(x) - min(x)
wynik = dane.agg({'wiek': zakres_wiekowy})DataFrame.sum - Return the sum over DataFrame axis.
DataFrame.cummax - Return cumulative maximum over DataFrame axis.
DataFrame.cummin - Return cumulative minimum over DataFrame axis.
DataFrame.cumsum - Return cumulative sum over DataFrame axis.
DataFrame.cumprod - Return cumulative product over a DataFrame or Series axis.
size
# Tabele grupujące
a = pd.DataFrame(dane.groupby('województwo'))
# Wczytywanie danych
# wczytaj = pd.read_csv('dane_pythossn.csv')
# print(wczytaj)
# Zapisywanie danych
# dane.to_excel('dane_python.xlsx')
# dane.to_csv('dane_pythona.xlsx', sep=',')Tworzenie nowych kolumn
Przegląd danych
Pierwsze 5 wierszy
print(dane.head().to_markdown(index=False))| id | wiek | płeć | województwo | kod ICD-10 | data | nazwa świadczenia | koszt świadczenia | zgon |
|-----:|-------:|:-------|:-------------------|:-------------|:-----------|:--------------------|--------------------:|:-------|
| 1 | 49 | M | podlaskie | K21 | 2017-04-23 | EKG | 231.12 | tak |
| 2 | 97 | M | dolnośląskie | L20 | 2015-08-03 | EKG | 902.66 | nie |
| 3 | 53 | M | wielkopolskie | L20 | 2018-05-04 | EKG | 479.85 | tak |
| 4 | 5 | K | małopolskie | J18 | 2016-09-26 | Badanie krwi | 175.63 | nie |
| 5 | 33 | K | kujawsko-pomorskie | E11 | 2020-07-09 | USG | 194.29 | nie |
Ostatnie 5 wierszy
print("Ostatnie 5 wierszy: \n",
tabulate(
dane.tail()))Ostatnie 5 wierszy:
-- --- -- - ----------- --- ---------- --------------------------- ------ ---
95 96 40 M łódzkie E11 2018-06-03 Konsultacja specjalistyczna 406.35 nie
96 97 73 K śląskie E11 2016-12-29 EKG 571.01 tak
97 98 30 M małopolskie K21 2017-12-17 Konsultacja specjalistyczna 419.83 tak
98 99 37 K śląskie K21 2016-07-28 RTG 668.37 nie
99 100 23 M łódzkie I10 2019-12-13 Badanie krwi 177.85 nie
-- --- -- - ----------- --- ---------- --------------------------- ------ ---
Podsumowanie zbioru
print("Podsumowanie zbioru",
dane.info()) <class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 100 non-null int64
1 wiek 100 non-null int64
2 płeć 100 non-null object
3 województwo 100 non-null object
4 kod ICD-10 100 non-null object
5 data 100 non-null object
6 nazwa świadczenia 100 non-null object
7 koszt świadczenia 100 non-null float64
8 zgon 100 non-null object
dtypes: float64(1), int64(2), object(6)
memory usage: 7.2+ KB
Podsumowanie zbioru None
Statystyki opisowe
print("Statystyki opisowe:\n",
dane.describe().to_markdown(index=False))Statystyki opisowe:
| id | wiek | koszt świadczenia |
|---------:|--------:|--------------------:|
| 100 | 100 | 100 |
| 50.5 | 50.44 | 496.365 |
| 29.0115 | 27.461 | 249.534 |
| 1 | 0 | 102.91 |
| 25.75 | 29.5 | 282.21 |
| 50.5 | 51 | 438.86 |
| 75.25 | 71.25 | 678.285 |
| 100 | 100 | 965.76 |
Porównanie funkci R i Python
| Opis funkcji | Python | R |
|---|---|---|
| Instalacja pakietów | import nazwa_pakietu | library(nazwa_pakietu) |
| Ramki danych | data.frame(dane) | Data.Frame(dane) |
| Tabele html | tabulate(dataframe) | kable(dataframe) |
| Podsumowanie zbioru | dane.info( | str(dane) |
| Ramki danych | dane.head() | head(dane) |
| Tabele html | dane.describe() | summary(dane) |
Tworzenie tabel
tabulate
from tabulate import tabulate
print(tabulate(dane.head(),
headers='keys',
tablefmt='pipe',
showindex=False))| id | wiek | płeć | województwo | kod ICD-10 | data | nazwa świadczenia | koszt świadczenia | zgon |
|-----:|-------:|:-------|:-------------------|:-------------|:-----------|:--------------------|--------------------:|:-------|
| 1 | 49 | M | podlaskie | K21 | 2017-04-23 | EKG | 231.12 | tak |
| 2 | 97 | M | dolnośląskie | L20 | 2015-08-03 | EKG | 902.66 | nie |
| 3 | 53 | M | wielkopolskie | L20 | 2018-05-04 | EKG | 479.85 | tak |
| 4 | 5 | K | małopolskie | J18 | 2016-09-26 | Badanie krwi | 175.63 | nie |
| 5 | 33 | K | kujawsko-pomorskie | E11 | 2020-07-09 | USG | 194.29 | nie |
markdown
print(dane.head().to_markdown(index = False))| id | wiek | płeć | województwo | kod ICD-10 | data | nazwa świadczenia | koszt świadczenia | zgon |
|-----:|-------:|:-------|:-------------------|:-------------|:-----------|:--------------------|--------------------:|:-------|
| 1 | 49 | M | podlaskie | K21 | 2017-04-23 | EKG | 231.12 | tak |
| 2 | 97 | M | dolnośląskie | L20 | 2015-08-03 | EKG | 902.66 | nie |
| 3 | 53 | M | wielkopolskie | L20 | 2018-05-04 | EKG | 479.85 | tak |
| 4 | 5 | K | małopolskie | J18 | 2016-09-26 | Badanie krwi | 175.63 | nie |
| 5 | 33 | K | kujawsko-pomorskie | E11 | 2020-07-09 | USG | 194.29 | nie |
import pandas as pd