Jak znając SQL w ciągu godziny zacząć pisać w Pythonie?

Uwielbiam pisać zapytania SQL-owe. Są one logiczne, dokładne, a przy odpowiednim formatowaniu – przejrzyste. Ale trzeba zdawać sobie sprawę, że SQL nie jest idealny do wszystkich zastosowań. W tym wpisie postanowiłem pokazać jak łatwo przestawić się z pisania zapytań SQL na Pythona, a dokładniej Pandas.

Wróćmy jeszcze na chwilę do wstępu dzisiejszego wpisu. Dlaczego właściwie SQL nie jest dobry na wszystko? W jakich sytuacjach nie ma wystarczających funkcjonalności? – zapytacie. SQL jest idealny do pozyskiwania danych z różnych tabel hurtowni. Zgrabnie napisane zapytania oszczędza analitykowi masę pracy i pozwala wydobyć głębię oraz wartość biznesową drzemiącą w danych firmowych. Ok – mamy już dane i teraz chcemy trochę z nimi podziałać. Dołączyć inną tabelkę, zmienić formaty czy kolejność kolumn możemy oczywiście również z poziomu SQL Developera. Czasem brakuje nam przestrzeni roboczej do odkładania tymczasowych tabel, a musicie przyznać, że zabawa z WITH w SQL nieco zaciemnia obraz kodu. Czasem musi także “wpuścić bokiem” jakiego Excela lub csv z danymi do analizy.

Jest kilka rozwiązań produktowych, które tworzą dla użytkownika przestrzeń do zabawy z danymi i umożliwiają łatwą obsługę importu plików. Należą do nich m.in.:

  1. Microsoft SQL Server
  2. SAS Enterprise Guide
  3. Python (a w szczególności jego biblioteka Pandas).

Ostatnio trochę było na blogu o SASie – jest to oprogramowanie, którego używam na co dzień i bardzo to sobie chwalę (a pisałem o tym w tym artykule). Jednak w związku z niesłabnącą popularnością Pythona tym razem postanowiłem “skręcić” na blogu nieco w kierunku tego open source’owego oprogramowania.

Artykuł będzie krótkim wprowadzeniem do Pythona dla SQLowców. Kilka informacji o tym jak przygotować sobie środowisko do pisania w Pythonie znajdziesz w jednym z moich poprzednich artykułów tutaj.

Chcę, żebyś ćwiczył razem ze mną. Dlatego fajnie będzie, jeśli pobierzesz pliki z danymi, które wykorzystuję w dzisiejszym artykule.

Dane, na których będziemy pracować dotyczą Formuły 1. Znajdziesz tu informację m.in. o kierowcach, którzy startowali w wyścigach. Pliki z danymi pobrałem ze zbiorów Kaggle. Dokładnie to wszystkie pliki znajdziesz TUTAJ.

Formula 1 Race Data – zbiór dostępny na Kaggle

Zanim zaczniemy zabawy z przepisywaniem komend SQL na Pythona warto załadować nasz plik z danymi. Odpalam Jupytera, wrzucam plik do przestrzeni roboczej i piszę poniższe polecenia:

import pandas as pd
 
drivers = pd.read_csv("drivers.csv")

Jesteśmy więc gotowi i tym samym zaczynamy.


Wyświetlanie wszystkich danych z tabeli

Klasyczna komenda SQL w Pythonie wygląda jeszcze lepiej. Wystarczy po prostu napisać nazwę ramki danych, do której załadowaliśmy naszą tabelę:

#SQL:
#SELECT * FROM drivers;
#----
#PYTHON:
drivers

Wyświetlanie pierwszych wierszy z tabeli

Załóżmy, że chcemy zobaczyć próbkę danych w tabeli – na przykład pierwszych 10 wierszy. Najpierw SQL (używamy ROWNUM), a później Python z użyciem funkcji head(n). Liczba w nawiasie określa liczbę wierszy do wyświetlenia. Jeśli pozostawisz ją pustą, to z automatu zobaczysz pierwszych 5 wierszy.

#SQL:
#SELECT * FROM drivers WHERE ROWNUM <=10;
#----
#PYTHON:
drivers.head(10)

Dołącz do Newslettera
Potwierdzam zapis na listę mailową!!!
Dołącz do listy mailowej ZobaczDane.pl. Dzięki temu od razu dostaniesz informację, gdy na blogu pojawi się nowy artykuł. Dodatkowo co tydzień wyślę Ci zbiór kilku ciekawych linków dotyczących zagadnień ze świata danych.
Nie będę wysyłał Ci żadnego spamu. U mnie masz same konkrety.

Wybieranie określonych wierszy – jeden warunek

Jeśli chcesz wybrać jedynie wiersze, które spełniają określony warunek to w SQL użyjesz oczywiście słowa WHERE. W Pythonie sprawa wygląda również dość prosto – pamiętaj, żeby używać podwójnego symbolu “=”:

#SQL:
#SELECT * FROM drivers WHERE Nationality = 'Spanish';
#----
#PYTHON:
drivers[drivers.nationality == 'Spanish']

Wybieranie określonych wierszy i kolumn – jeden warunek i jedna kolumna

W SQL po słowie SELECT podajemy listę kolumn do wyświetlania (w tym przypadku jedna kolumna). Z kolei w Pythonie użyjemy takiej konstrukcji:

#SQL:
#SELECT driverRef FROM drivers WHERE Nationality = 'Spanish';
#----
#PYTHON:
drivers[drivers.nationality == 'Spanish'].driverRef

Wybieranie wierszy w oparciu o kilka warunków

Czasem jeden warunek nie wystarczy, aby wybrać pożądane obserwacje. W SQL możemy łączyć warunki korzystając ze słów AND oraz OR. W Pythonie mamy “&” oraz “|“:

#SQL:
#SELECT driverRef FROM drivers WHERE (Nationality = 'Spanish' AND forename = 'Emilio');
#----
#PYTHON:
drivers[(drivers.nationality == 'Spanish') & (drivers.forename == 'Emilio')]

Wybieranie wierszy w oparciu o kilka warunków – tylko niektóre kolumny

Możemy dodatkowo ograniczać zakres wyświetlanych kolumn. W SQL wystarczy, że wymienimy te pożądane po słowie SELECT, w Python posługujemy się listą kolumn:

#SQL:
#SELECT driverId, forename, surname, dob
#FROM drivers
#WHERE (nationality = 'Spanish' AND forename = 'Emilio');
#----
#PYTHON:
drivers[(drivers.nationality == 'Spanish') & (drivers.forename == 'Emilio')][['driverId', 'forename', 'surname', 'dob']]

Podstawowe funkcje agregujące

Widok wszystkich danych spełniających określony przez nas warunek jest super. Najczęściej jednak, gdy mówimy o danych liczbowych to nie interesują nas wszystkie dane, ale pewne związane z nimi statystyki. Dobrze jest znać minimalną, maksymalną i średnią wartość w zbiorze obserwacji. Funkcje SQL takie jak min, max, avg mają swoje odpowiedniki w Pythonie.

#SQL:
#SELECT min(number), max(number), avg(number)
#FROM drivers;
#----
#PYTHON:
drivers.agg({'number' : ['mean', 'min', 'max']})

Wybieranie niepowtarzalnych wartości w ramach danej kolumny

Niepowtarzalne (unikatowe) wartości przydają się wszędzie tam, gdzie pracujemy na danych sprzedażowych. Rodzajów produktów w sklepie czy w banku być może jest i dużo. Jednak najczęściej transakcji na poszczególnych produktach jest dużo dużo więcej. W jaki sposób sprawdzić jakie produkty zostały sprzedane? W SQL mamy słowo DISTINCT, które w Pythonie ma swój odpowiednik w funkcji unique().

#SQL:
#SELECT DISTINCT surname
#FROM drivers;
#----
#PYTHON:
drivers.surname.unique()

Szeregowanie wartości w zadanej kolejności

Układanie wartości w kolejności malejącej lub rosnącej zwiększa przejrzystość danych, niejednokrotnie pozwala na znajdowanie błędów, a poprzez zakładanie indeksów zwiększa szybkość wykonywania zapytań w SQL. Oczywiście w bibliotece Pandas mamy odpowiednika ORDER BY.

#SQL:
#SELECT *
#FROM drivers
#WHERE nationality = 'German' 
#ORDER BY surname;
#----
#PYTHON:
drivers[drivers.nationality == 'German'].sort_values('surname')

… i jeszcze kolejność malejąca:

#SQL:
#SELECT *
#FROM drivers
#WHERE nationality = 'German' 
#ORDER BY surname DESC;
#----
#PYTHON:
drivers[drivers.nationality == 'German'].sort_values('surname', ascending = False)

Grupowanie elementów

Tak jak wcześniej wspominałem, bardzo dobrze jest mieć wszystkie dane pod ręką i na widoku, ale zwykle najwięcej wartości przynosi nam analiza danych zagregowanych (inaczej zgrupowanych). Prosta komenda GROUP BY używana w SQL, niestety w Pythonie wygląda nieco gorzej:

#SQL:
#SELECT nationality, surname, count(*)
#FROM drivers
#GROUP BY nationality, surname;
#----
#PYTHON:
drivers.groupby(['nationality', 'surname']).size().to_frame('liczba_kierowcow').reset_index()

Czemu po instrukcji groupby mamy jeszcze kilka innych?
1) size() – zastępuje w tym przypadku znane z SQL COUNT(*)
2) opcja to_frame() zamienia typ wyświetlanych danych z listy na ramkę danych, w nawiasie wpisujemy jak będzie się nazywać kolumna ze zagregowanymi wartościami
3) reset_index() – pozwala na przepisanie wartości, po której grupujemy, w każdym wierszu wynikowym.

Żeby sprawdzić działanie każdej z powyższych opcji dobrze jest dopisywać je po kolei i weryfikować co się zmieniło.


Dołącz do Newslettera
Potwierdzam zapis na listę mailową!!!
Dołącz do listy mailowej ZobaczDane.pl. Dzięki temu od razu dostaniesz informację, gdy na blogu pojawi się nowy artykuł. Dodatkowo co tydzień wyślę Ci zbiór kilku ciekawych linków dotyczących zagadnień ze świata danych.
Nie będę wysyłał Ci żadnego spamu. U mnie masz same konkrety.

Grupowanie elementów z uszeregowaniem wyników

Aby jeszcze zwiększyć czytelność naszego raportu, często dodatkowo porządkujemy pogrupowane wartości. W SQL możemy to zrobić dodając po poleceniu GROUP BY, znane z wcześniejszych akapitów ORDER BY. A jak to wygląda w Pythonie?

#SQL:
#SELECT nationality, surname, count(*) as liczba_kierowcow
#FROM drivers
#GROUP BY nationality, surname
#ORDER BY count(*) DESC;
#----
#PYTHON:
drivers.groupby(['nationality', 'surname']).size().to_frame('liczba_kierowcow').reset_index().sort_values('liczba_kierowcow', ascending = False)

Filtrowanie zagregowanych wyników

Być może rzadziej używaną, ale niekiedy mega przydatną opcją jest możliwość sortowania w SQL już zagregowanych wyników. Komendą odpowiedzialną za taką operację w SQL jest HAVING. W Pythonie to już nie takie oczywiste…

#SQL:
#SELECT nationality, surname, count(*) as liczba_kierowcow
#FROM drivers
#GROUP BY nationality, surname
#HAVING count(*) > 1;
#----
#PYTHON:
drivers.groupby(['nationality', 'surname']).filter(lambda g: len(g) > 1).groupby(['nationality', 'surname']).size().to_frame('liczba_kierowcow').reset_index()

Użyta powyżej funkcja lambda w tym przypadku sprawdza liczbę wystąpień kierowców z jednego kraju o takim samym nazwisku. Więcej o tej funkcji możesz przeczytać tutaj.


Na zakończenie

Myślę, że dzisiejszy wpis będzie dla Ciebie przydatny. Nie musisz skakać po forach lub książkach – wszystko masz w jednym miejscu. Ten artykuł pisałem również dla siebie, żeby to co potrzebuję mieć zawsze pod ręką bez konieczności poszukiwań.

W kolejnym wpisie opowiem więcej o tym jak w Pythonie napisać SQL-owe łączenia JOIN, jak wygląda Pythonowy UNION oraz jak dodawać, aktualizować i usuwać informacje z ramki danych.

Polecam inne artykuły na blogu – np. ten o Trikach Excela. Jeśli jeszcze tego nie zrobiłeś, to możesz zapisać się na mój newsletter i zawsze w pierwszej kolejności dowiadywać się o nowościach ze świata danych i na blogu. Zapisać się możesz korzystając z poniższego formularza.

Dołącz do Newslettera
Potwierdzam zapis na listę mailową!!!
Dołącz do listy mailowej ZobaczDane.pl. Dzięki temu od razu dostaniesz informację, gdy na blogu pojawi się nowy artykuł. Dodatkowo co tydzień wyślę Ci zbiór kilku ciekawych linków dotyczących zagadnień ze świata danych.
Nie będę wysyłał Ci żadnego spamu. U mnie masz same konkrety.

Tyle na dzisiaj i do zobaczenia!!!

Może Ci się spodobać...

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *