Transformacja to przekształcanie surowych danych w formę użyteczną do analizy. Obejmuje tworzenie nowych kolumn, sortowanie, grupowanie, agregację i łączenie tabel.
Dodawanie i modyfikowanie kolumn
library (dplyr)
pracownicy <- data.frame (
imie = c ("Anna" , "Piotr" , "Kasia" , "Marek" , "Zofia" ),
pensja = c (4500 , 5200 , 4800 , 6100 , 5500 ),
dzial = c ("IT" , "Finanse" , "IT" , "HR" , "Finanse" ),
staz_lat = c (3 , 7 , 2 , 10 , 5 ),
czy_menedz = c (FALSE , TRUE , FALSE , TRUE , FALSE )
)
# Dodanie nowych kolumn — mutate()
pracownicy <- pracownicy |>
mutate (
pensja_netto = pensja * 0.77 , # obliczenie
doswiadczony = staz_lat >= 5 , # warunek logiczny
kategoria = case_when ( # wiele warunków
pensja < 5000 ~ "junior" ,
pensja < 6000 ~ "mid" ,
TRUE ~ "senior"
)
)
pracownicy
#> imie pensja dzial staz_lat czy_menedz pensja_netto doswiadczony kategoria
#> 1 Anna 4500 IT 3 FALSE 3465 FALSE junior
#> 2 Piotr 5200 Finanse 7 TRUE 4004 TRUE mid
#> 3 Kasia 4800 IT 2 FALSE 3696 FALSE junior
#> 4 Marek 6100 HR 10 TRUE 4697 TRUE senior
#> 5 Zofia 5500 Finanse 5 FALSE 4235 TRUE mid
# Usunięcie kolumny
pracownicy <- pracownicy |>
select (- pensja_netto)
# Zmiana nazwy kolumny
pracownicy <- pracownicy |>
rename (lata_pracy = staz_lat)
names (pracownicy)
#> [1] "imie" "pensja" "dzial" "lata_pracy" "czy_menedz"
#> [6] "doswiadczony" "kategoria"
import pandas as pd
import numpy as np
pracownicy = pd.DataFrame({
"imie" : ["Anna" , "Piotr" , "Kasia" , "Marek" , "Zofia" ],
"pensja" : [4500 , 5200 , 4800 , 6100 , 5500 ],
"dzial" : ["IT" , "Finanse" , "IT" , "HR" , "Finanse" ],
"staz_lat" : [3 , 7 , 2 , 10 , 5 ],
"czy_menedz" : [False , True , False , True , False ]
})
# Dodanie nowych kolumn
pracownicy["pensja_netto" ] = pracownicy["pensja" ] * 0.77 # obliczenie
pracownicy["doswiadczony" ] = pracownicy["staz_lat" ] >= 5 # warunek logiczny
# Wiele warunków — np.select()
warunki = [pracownicy["pensja" ] < 5000 , pracownicy["pensja" ] < 6000 ]
wartosci = ["junior" , "mid" ]
pracownicy["kategoria" ] = np.select(warunki, wartosci, default= "senior" )
pracownicy
# Usunięcie kolumny
pracownicy = pracownicy.drop(columns= ["pensja_netto" ])
# Zmiana nazwy kolumny
pracownicy = pracownicy.rename(columns= {"staz_lat" : "lata_pracy" })
list (pracownicy.columns)
Sortowanie
# Sortowanie rosnąco
arrange (pracownicy, pensja)
#> imie pensja dzial lata_pracy czy_menedz doswiadczony kategoria
#> 1 Anna 4500 IT 3 FALSE FALSE junior
#> 2 Kasia 4800 IT 2 FALSE FALSE junior
#> 3 Piotr 5200 Finanse 7 TRUE TRUE mid
#> 4 Zofia 5500 Finanse 5 FALSE TRUE mid
#> 5 Marek 6100 HR 10 TRUE TRUE senior
# Sortowanie malejąco
arrange (pracownicy, desc (pensja))
#> imie pensja dzial lata_pracy czy_menedz doswiadczony kategoria
#> 1 Marek 6100 HR 10 TRUE TRUE senior
#> 2 Zofia 5500 Finanse 5 FALSE TRUE mid
#> 3 Piotr 5200 Finanse 7 TRUE TRUE mid
#> 4 Kasia 4800 IT 2 FALSE FALSE junior
#> 5 Anna 4500 IT 3 FALSE FALSE junior
# Sortowanie po wielu kolumnach
arrange (pracownicy, dzial, desc (pensja))
#> imie pensja dzial lata_pracy czy_menedz doswiadczony kategoria
#> 1 Zofia 5500 Finanse 5 FALSE TRUE mid
#> 2 Piotr 5200 Finanse 7 TRUE TRUE mid
#> 3 Marek 6100 HR 10 TRUE TRUE senior
#> 4 Kasia 4800 IT 2 FALSE FALSE junior
#> 5 Anna 4500 IT 3 FALSE FALSE junior
# Sortowanie rosnąco
pracownicy.sort_values("pensja" )
# Sortowanie malejąco
pracownicy.sort_values("pensja" , ascending= False )
# Sortowanie po wielu kolumnach
pracownicy.sort_values(["dzial" , "pensja" ], ascending= [True , False ])
Grupowanie i agregacja
Grupowanie w R/Pythonie to odpowiednik tabeli przestawnej w Excelu — tylko że wynik to zwykła ramka danych, którą możesz dowolnie dalej przetwarzać.
# Podstawowa agregacja — średnia pensja według działu
pracownicy |>
group_by (dzial) |>
summarise (
srednia_pensja = mean (pensja),
mediana_pensja = median (pensja),
liczba_osob = n ()
)
#> # A tibble: 3 × 4
#> dzial srednia_pensja mediana_pensja liczba_osob
#> <chr> <dbl> <dbl> <int>
#> 1 Finanse 5350 5350 2
#> 2 HR 6100 6100 1
#> 3 IT 4650 4650 2
# Agregacja po wielu grupach
pracownicy |>
group_by (dzial, kategoria) |>
summarise (
srednia = mean (pensja),
min_pens = min (pensja),
max_pens = max (pensja),
.groups = "drop" # usuwa grupowanie po agregacji
) |>
arrange (dzial, srednia)
#> # A tibble: 3 × 5
#> dzial kategoria srednia min_pens max_pens
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 Finanse mid 5350 5200 5500
#> 2 HR senior 6100 6100 6100
#> 3 IT junior 4650 4500 4800
# Podstawowa agregacja
pracownicy.groupby("dzial" )["pensja" ].agg(
srednia_pensja= "mean" ,
mediana_pensja= "median" ,
liczba_osob= "count"
).reset_index()
# Agregacja po wielu grupach
(pracownicy
.groupby(["dzial" , "kategoria" ])
.agg(
srednia = ("pensja" , "mean" ),
min_pens = ("pensja" , "min" ),
max_pens = ("pensja" , "max" )
)
.reset_index()
.sort_values(["dzial" , "srednia" ])
)
Łączenie tabel
Łączenie tabel to odpowiednik funkcji WYSZUKAJ.PIONOWO (VLOOKUP) lub relacji w Power Pivot — ale bardziej elastyczne i odporne na błędy.
# Tabela z informacjami o działach
dzialy <- data.frame (
dzial = c ("IT" , "Finanse" , "HR" ),
budzet = c (500000 , 350000 , 200000 ),
lokalizacja = c ("Warszawa" , "Kraków" , "Warszawa" )
)
# LEFT JOIN — wszyscy pracownicy + pasujące info o dziale
left_join (pracownicy, dzialy, by = "dzial" )
#> imie pensja dzial lata_pracy czy_menedz doswiadczony kategoria budzet
#> 1 Anna 4500 IT 3 FALSE FALSE junior 500000
#> 2 Piotr 5200 Finanse 7 TRUE TRUE mid 350000
#> 3 Kasia 4800 IT 2 FALSE FALSE junior 500000
#> 4 Marek 6100 HR 10 TRUE TRUE senior 200000
#> 5 Zofia 5500 Finanse 5 FALSE TRUE mid 350000
#> lokalizacja
#> 1 Warszawa
#> 2 Kraków
#> 3 Warszawa
#> 4 Warszawa
#> 5 Kraków
# INNER JOIN — tylko wiersze pasujące w obu tabelach
inner_join (pracownicy, dzialy, by = "dzial" )
#> imie pensja dzial lata_pracy czy_menedz doswiadczony kategoria budzet
#> 1 Anna 4500 IT 3 FALSE FALSE junior 500000
#> 2 Piotr 5200 Finanse 7 TRUE TRUE mid 350000
#> 3 Kasia 4800 IT 2 FALSE FALSE junior 500000
#> 4 Marek 6100 HR 10 TRUE TRUE senior 200000
#> 5 Zofia 5500 Finanse 5 FALSE TRUE mid 350000
#> lokalizacja
#> 1 Warszawa
#> 2 Kraków
#> 3 Warszawa
#> 4 Warszawa
#> 5 Kraków
# Dostępne typy: left_join, right_join, inner_join, full_join
# Tabela z informacjami o działach
dzialy = pd.DataFrame({
"dzial" : ["IT" , "Finanse" , "HR" ],
"budzet" : [500000 , 350000 , 200000 ],
"lokalizacja" : ["Warszawa" , "Kraków" , "Warszawa" ]
})
# LEFT JOIN
pd.merge(pracownicy, dzialy, on= "dzial" , how= "left" )
# INNER JOIN
pd.merge(pracownicy, dzialy, on= "dzial" , how= "inner" )
# Dostępne typy: how="left", "right", "inner", "outer"