Wprowadzenie do pandas (Python)

06 Jan 2020 / admin

W tym wpisie spróbuję napisać krótkie wprowadznie do modułu (biblioteki) pandas. Obiekt pandas DataFrame służy nam do prostych operacji na danych, początkowe wrażenie jest takie jak byśmy operowali na dużym arkuszu kalkulacyjnym. Róznica jest taka, że pandas potrafi dużo więcej (zobacz wpis o operacjach groupby itp.) i a operacje wykonywane są znacznie szybciej. Przed prezentacją podstaw "pandy" dodajmy, że podobne konstrukcje występują w wielu programach do obliczeń statystycznych (np. data frame albo data table w R). Przed dalszymi krokami zaimportujemy moduł komendą import pandas as pd (będziemy często odwoływać się do pandas, więc wygodnie będzie nam używać "aliasu" pd).
Utwórzmy zatem przykładowy DataFrame, złożony z 2 kolumn i 5 wierszy (co można później sprawdzić wykonując komendę df1.shape).

df1 = pd.DataFrame({"col_a": [1, 2, 3, 5, 10], "col_b": [10, 10, 20, 25, 20]})

Aby poznać podstawy, spróbujmy przeprowadzić kilka prostych operacji:

  • odwołanie do pojedynczej kolumny: df1.col_a lub df1['col_a']
  • odwołanie do kilku kolumn: df1[lista_kolumn] - np. df1[['col_a', 'col_b']]
  • odwołanie do wybranych wierszy kolumny: df1.col_a[2:4] lub df1['col_a'][2:4] (domyślnie indeksowanie tak jak w listach, czyli od zera, ale jeśli chcemy możemy zmienić indeksy)

Oczywiście na wynikach tych operacji (czyli pojedynczej kolumnie lub wycinku ramki danych) chcemy przeprowadzić obliczenia. Spójrzmy na te przykłady:

  • suma z danej kolumny: df1.col_a.sum() lub df1['col_a'].sum()(oczywiście analogicznie możemy obliczyć sumę "wycinka" - wybranych wierszy pojedynczej kolumny)
  • średnia z danej kolumny: df1.col_a.mean() lub df1['col_a'].mean()
  • podobnie możemy skorzystać z metod np.: .std() (odchylenie standardowe), .min(), .max(), .cumsum() (skumulowana suma)
  • radzenie sobie z obserwcjami - brakami danych (not a number: NaN lub np.nan): df1.dropna() () lub df1.fillna(-99) (zastąpienie NaN na podaną wartość, np. -99)
  • suma kolumn DataFrame: df1.sum(axis=0)
  • suma wierszy DataFrame: df1.sum(axis=1)

df1.head() - ogląd danych (wyświetla pierwszych kilka wierszy) df1.columns - lista kolumn c.d.n.

Operacja na zbiorach danych (w Python i R) - cz. 1

18 Aug 2018 / admin

Już pisałem, że same obliczenia zwykle zajmują 10-15% czasu. Z pozostałych 85-90% większość trzeba przezanczyć na sprawdzenie i przekształcanie danych. Dziś przestawię jak efektywnie przeszktałcać dane w Python (będzie też trochę o R). Wyobrażmy sobie, że mamy tabelę (ramkę danych) z codziennymi wydatkami, np.:

KATEGORIA CENA ILOSC WART
Żywność 1,5 2 3
Rozrywka 24 1 24
Żywność 4 5 20
Ubrania 99 1 99
Ubrania 25 2 50
Żywność 3 1 3
Żywność 0,5 40 20
Rozrywka 7,5 3 22,5
Żywność 14,99 3 44,97
Rozrywka 50 1 50


Naturalnym problemem analitycznym jest policzenie sumy wydaktów dla każdej kategorii. Wydawać się może, że osiągniemy to przy pomocy pętli, coś w rodzaju:

  • Weź zmienną SUMA = 0
  • Kolejno dla wierszy i = 1,...,N (gdzie N to liczba wierszy) wykonaj polecenia:
    • Sprawdź czy kolumna KATEGORIA == "Żywność"
    • Jeśli powyższy warunek jest prawdziwy to dodaj do zmiennej SUMA wartość kolumny WART


Następnie to samo to dla kategorii "Ubrania" i "Rozrywka". Takie rozwiązanie zadziała i otrzymany prawidłowy wyniki (90,97), ale można lepiej (bardziej zwięzły zapis i znacznie krótszy czas niezbędny do obliczenia). Takie operacje na danych to standardowa operacja agregująca ("GROUP BY" w SQL), standardowo zaimplementowana w bazach danych np. SQL, ale także w Python (Pandas) i R (data.table albo dplyr). W takiej operacji podajemy zmienną grupującą (czyli zmienną, która rozróżnia podgrupy, tu: KATEGORIA) i operacje jakie chcemy wykonać w każdej z podgrup (tu: suma zmiennej WART). Oczywiście potencjalny wachlarz zastosować to nie tylko suma, równie często korzystamy ze średniej i liczby wystąpień ("COUNT" w SQL) albo liczby unikalnych wartości danej zmiennej ("COUNT DISTINCT").

Przykład z życia wzięty.

W bazie danych z niewiadonych przyczyn "pojawiły się" braki obseracji. Skonstruowałem indykator (zmienną zerojedynkową) dla braku danych i okazało się, że udział braków danych sięga ok. 40%. Przyjrzyjmy się temu bliżej - policzyłem udział braków danych wg miejscowości, wyniki są takie:

Zgierz 0
Łódź 1
Ostrołęka 1
Warszawa 0
Radomsko 0
Pabianice 0
Piotrków Tryb. 1
Tomaszów Maz. 1
Kalisz 0


Widzicie to co ja? Braki obserwacji są tylko dla tych miejscowości, które mają "polskie litery". To pokazało, gdzie tkwi problem - różne kodowanie polskich znaków w różnych plikach (baza powstawała poprzez łączenie różnych zbiorów danych). Teraz rozwiązanie problemu zajęło mniej niż 5 minut.

Przykładowe kody (implementacja w Pandas + Python i Data.table + R)

Okazuje się, że implementacja przedstawionych wyżej operacji jest bardzo prosta i przyjemna, zarówno w Python jak i R. Przy okazji tych przykładów podaję odpowiedniki komend dla zapytań SQL -- przyda się tym, którzy znają choćby podstawy SQL albo gdy chcecie wyjaśnić sens jakieś operacji "czystemu" programiście.
Poniżej kody, przy założeniu że mamy w pamięci ramkę danych o nazwie DF, zawierającą zmienne Kategoria i Wartosc.

Operacje group by w Python - Pandas import pandas as pd
# wprowadz ramke danych, np. DF = pd.DataFrame( {"Wart": [0,1,3,3,4,5,6,6,8,8], "Kategoria": [1,1,1,1,2,2,2,2,2,2]} )
DF.groupby(by = "Kategoria").sum()
DF.groupby(by = "Kategoria").count()
DF.groupby(by = "Kategoria").unique()
DF.groupby(by = "Kategoria").nunique()
# Trochę bardziej elegancko
DF_GroupBy = DF.groupby(by = "Kategoria")
DF_GroupBy.sum()
DF_GroupBy.count()    # itd.


Operacje group by w R - data.table library(data.table)
# wprowadz ramke danych, np. DF = data.frame( Wart = c(0,1,3,3,4,5,6,6,8,8), Kategoria = c(1,1,1,1,2,2,2,2,2,2) )
DF = data.table(DF)
DF[ , .(Suma = sum(Wart)), by = Kategoria]
DF[ , .N, by = Kategoria]
DF[ , .(Unikalne = unique(Wart)), by = Kategoria]
DF[ , .(L_Unikalnych = length(unique(Wart))), b = Kategoria]

R czy Python? Jaki język wybrać

07 Jan 2018 / admin

Data science zdominowały R i Python. Który wybrać?


Początkowo nie ma to wielkiego znaczenia (musimy poznać metody, a te w zasadzie nie zależą od implementacji). Problem ten pojawia się gdy chcemy nabrać praktyki, wykonać jakieś ćwiczenia na danych. Poniżej fajne strony w tej kwestii, odniosę się do nich bliżej wkrótce.
R czy Python [datacamp.com]
R czy Python [webhose.io]

W krótkich żołnierskich słowach -- główna różnica pomiędzy R a Py to punkt wyjścia twórców.

  • R jest bardziej pakietem statystycznym (najbardziej przypomina Matlab, ale jego przeznaczeniem jest wykonywanie obliczeń - jak w Mathematica, Statistica, Stata, SPSS czy Gretl). Dlatego R domyślnie wyświetla wyniki na ekranie, podstawowym rodzajem danych jest wektor, domyślnie posiada też pakiet DataFrame (dla niewtajemniczonych: daleki odpowienidk arkusza w Excelu).
  • Python jest pomyślany jako język programowania, wobec czego niekoniecznie musi być używany do obliczeń (można w nim napisać np. grę komputerową). Oczywiście w ramach pakietu R możemy używać skryptów i funkcji, napisanych w języku R.
  • Dzięki dodatkowym bibliotekom, różnice pomiędzy R a Python zmniejszają się. Np. używając biblioteki pandas możemy obrabiać dane podobnie jak w R. Istnieje sporo bliżniaczych (R / Py) bibliotek, np. Keras, NLTK, Selenium, itp.
  • Pomiędzy tymi pakietami jest wiele podobieństw. Oba są darmowe (w przeciwieństwie do Matlab), oba mają bogaty zasób bibliotek do data-science. Skrypty w R są interpretowane, podobnie jak programy w Py.

Jeśli bliższe Ci jest programowanie niż algebra czy statystyka - zapewnie będziesz zadowolony z Python (ale z drugiej strony w data-science oba komponenty są nieuniknione: programowanie oraz praca na wzorach i danych).
Jeśli używałeś Matlaba - łatwiej zaczniesz z R (zob. słownik R-Matlab).
Jeśli naturalnym sposobem zapisu jest wektor/macierz i większość operacji będzie wykonywana "wektorowo" - polubisz R.
Jeśli lubisz oglądać dane i na bieżąco wyniki na ekranie - raczej R.
Jeśli Twój program będzie działał na serwerze albo na przenośmym środowisku na USB - znacznie łatwiej to osiągniesz używając Python.

Moim naturalnym punktem wyjścia jest oczywiście praca na danych. Dzięki doświadczeniu w Matlab, kiedy potrzebowałem przesiąść się na R - zajęło mi to kilka dni metodą prób i błędów. Rozpoczęscie obliczeń w Python trwało trochę dłużej, mimo że znałem podstawy programowania. Mimo wszystko -- sam wolę Py i nowe projekty staram się robić w tym języku. Nie oznacza to, że tego co robię nie można zrobić w R! Dla obecnych zastosowań nie wielkich różnic, a osobście podoba mi się zwięzłość Py. Wydaje mi się, że środowisko użytkowników Py zapewnia trochę więcej wsparcia np. na stackoverflow.com.

Oczywiście w pracy zespołowej, nie zawsze mamy wybór. Przykładowo -- trafiam do zespołu, który ma rozpoczęty projekt albo mój szef ma silną preferencję któregoś z podejść. Poza tym polityka bezpieczeństwa firmy może nie pozwalać na instalację R czy Python. Na początek zacznij od tego podejścia, które wolisz, a prędzej czy później dojdziesz do tego, że warto poznać choćby podstawy innych podejść (być może nie tylko z grona R/Py).



1