Tworzenie bloków Gutenberg z użyciem ChatGPT.

Zobacz kurs

Podstawy AWS.

Automatyzacja procesów z Make.com

Najlepsze wtyczki do sprzedaży biletów na WordPressie

Najlepsze wtyczki do sprzedaży biletów na WordPressie

Odkryj Interactivity API w WordPressie

Odkryj Interactivity API w WordPressie

Optymalizacja TTFB: Klucz do szybszej i bardziej responsywnej strony internetowej

Optymalizacja TTFB: Klucz do szybszej i bardziej responsywnej strony internetowej

Najczęściej popełniane błędy przez programistów React i jak ich unikać

Najczęściej popełniane błędy przez programistów React i jak ich unikać

WordPress i Block Protocol: Nowa przyszłość dla twórców i deweloperów

WordPress i Block Protocol: Nowa przyszłość dla twórców i deweloperów

Zobacz więcej
Jak wykonać transkrypcję wideo przy użyciu modelu Whisper od OpenAI

Jak wykonać transkrypcję wideo przy użyciu modelu Whisper od OpenAI

Superinteligencja: Czy prawda jest bardziej brutalna, niż się spodziewamy?

Superinteligencja: Czy prawda jest bardziej brutalna, niż się spodziewamy?

Jak wyprzedzić konkurencję dzięki EU AI Act – Przewodnik dla firm

Jak wyprzedzić konkurencję dzięki EU AI Act – Przewodnik dla firm

Nowe horyzonty sztucznej inteligencji z modelami Claude 3.5 od Anthropic

Nowe horyzonty sztucznej inteligencji z modelami Claude 3.5 od Anthropic

Kotaemon – Test narzędzia open-source RAG do budowania i eksploracji własnej bazy wiedzy

Kotaemon – Test narzędzia open-source RAG do budowania i eksploracji własnej bazy wiedzy

Zobacz więcej

Wstęp do przetwarzania i analizy danych z biblioteką Pandas

Awatar Mike Tomala

W świecie machine learning, gdzie przetwarzanie danych odgrywa kluczową rolę, nie można przejść obojętnie obok biblioteki Pandas w języku Python. To narzędzie nie tylko ułatwia manipulację danymi, ale także dostarcza potężne funkcje do ich analizy. Dla specjalisty od machine learning, głęboka znajomość pandas to niezwykle cenna umiejętność. Biblioteka ta umożliwia błyskawiczne wczytywanie, eksploracyjne przeglądanie i oczyszczanie danych – kluczowe etapy przygotowania danych do modelowania. Dzięki swojej prostocie i zaawansowanym możliwościom, pandas pozwala zoptymalizować proces manipulacji danymi, umożliwiając skupienie się na bardziej zaawansowanych aspektach, takich jak projektowanie i trenowanie modeli ML. Solidne zrozumienie tej biblioteki stwarza podstawy do efektywnego zarządzania danymi, co z kolei przekłada się na skuteczniejsze tworzenie i doskonalenie modeli predykcyjnych.

W tym wpisie postaram się zwinnie wprowadzić Cię w bibliotekę Pandas. Aby korzystać z biblioteki Pandas w Pythonie należy ją zaimportować, przykładowo w taki sposób:

import pandas as 

Podstawowe rodzaje obiektów

Wchodząc w obszar przetwarzania i analizy danych za pomocą biblioteki Pandas, kluczowym krokiem jest zrozumienie podstawowych rodzajów obiektów, które ta biblioteka oferuje. Pandas dostarcza trzy główne struktury danych: Series, DataFrame i Index.

Series to jednowymiarowa tablica, reprezentująca kolumnę danych, idealna do przechowywania pojedynczej cechy.

DataFrame, z kolei, to dwuwymiarowa struktura, przypominająca tabelę baz danych, gdzie każda kolumna może być rozważana jako osobna seria, a DataFrame jako kolekcja tych serii.

Wreszcie, Index pełni rolę jednoznacznego identyfikatora dla wierszy w DataFrame.

Znajomość tych podstawowych struktur stanowi solidny fundament dla precyzyjnej manipulacji i analizy danych, co z kolei przekłada się na bardziej zaawansowane eksploracje danych oraz efektywne budowanie i doskonalenie modeli machine learning.

Tworzymy DataFrame w Pandas

Teraz, gdy posiadamy pewną podstawową wiedzę na temat biblioteki Pandas i jej struktur danych, przejdźmy do praktyki. Tworzenie DataFrame z przykładowymi danymi stanowi pierwszy krok w eksploracji możliwości tej biblioteki. Przyjrzyjmy się prostemu przykładowi. Zakładając, że mamy listę słowników, gdzie każdy słownik reprezentuje dane dla jednego wiersza, możemy użyć funkcji pd.DataFrame(), aby utworzyć naszą strukturę danych. Na przykład:

import pandas as pd

# Przykładowe dane w postaci listy słowników
dane = [
    {'Imię': 'John', 'Wiek': 28, 'Zawód': 'Inżynier'},
    {'Imię': 'Anna', 'Wiek': 35, 'Zawód': 'Analityk Danych'},
    {'Imię': 'Marcin', 'Wiek': 32, 'Zawód': 'Programista'}
]

# Utworzenie DataFrame
df = pd.DataFrame(dane)

# Wyświetlenie uzyskanego DataFrame
print(df)

To proste podejście pozwala nam szybko zainicjować i wyświetlić nasze dane. W wyniku otrzymamy:

     Imię  Wiek            Zawód
0    John    28         Inżynier
1    Anna    35  Analityk Danych
2  Marcin    32      Programista

Przejdźmy teraz do Series. Jest to struktura danych jednowymiarowa, idealna do przechowywania pojedynczej cechy, co sprawia, że jest niezwykle przydatna w kontekście pracy nad projektami machine learning. Aby utworzyć Series z przykładowymi danymi, możemy skorzystać z poniższego prostego przykładu:

import pandas as pd

# Przykładowe dane w postaci listy
dane = [10, 20, 30, 40, 50]

# Utworzenie Series
serie_danych = pd.Series(dane)

# Wyświetlenie uzyskanej Series
print(serie_danych)

W tym przypadku, przekazując listę danych do konstruktora pd.Series(), tworzymy obiekt Series, który przechowuje wartości 10, 20, 30, 40, 50. Series pozwala nam efektywnie operować na pojedynczych kolumnach danych.

Wczytywanie danych z CSV do DataFrame biblioteki Pandas

W procesie przetwarzania i analizy danych, istotnym etapem jest wczytanie danych do struktury do DataFrame w bibliotece Pandas. Przy pracy nad projektami machine learning, często dane są przechowywane w formie plików CSV, co czyni wczytywanie ich do DataFrame kluczowym zadaniem. Biblioteka pandas ułatwia ten proces za pomocą funkcji pd.read_csv(). Poniżej przedstawiam prosty przykład:

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv')

# Wyświetlenie kilku pierwszych wierszy DataFrame
print(df.head())

W tym fragmencie kodu, pd.read_csv() pozwala na szybkie wczytanie danych z pliku CSV i umieszczenie ich w strukturze DataFrame. Funkcja ta oferuje szereg opcji dostosowywania procesu wczytywania danych, co jest szczególnie ważne w przypadku rozbudowanych zbiorów danych. Warto zauważyć, że wczytywanie danych to punkt wyjścia do dalszej analizy, eksploracji i przygotowywania danych do procesu modelowania machine learning.

W naszym przykładzie powyżej, wczytujemy plik CSV zawierający listę najlepiej ocenianych anglojęzycznych filmów z bazy IMDb. Plik CSV jest udostępniony na platformie Kaggle: https://www.kaggle.com/datasets/alexq1111/imdb-top-rated-english-movies.

Wykonując powyższy kod otrzymamy rezultat:

   Unnamed: 0                movie_name  movie_year  movie_rating user_votes
0           0  The Shawshank Redemption        1994           9.3       2.8M
1           1             The Godfather        1972           9.2         2M
2           2           The Dark Knight        2008           9.0       2.8M
3           3     The Godfather Part II        1974           9.0       1.3M
4           4              12 Angry Men        1957           9.0       839K

Dlaczego otrzymaliśmy tylko 5 wierszy, gdy plik CSV zawiera ich na pewno znacznie więcej? Dzieje się tak dzięki zastosowaniu na obiekcie typu DataFrame metody .head(), która pozwala na szybką inspekcję 5 górnych wierszy. Jak sprawdzić ile w rzeczywistości wierszy zawiera nasz obiekt DataFrame? W celu sprawdzenia możemy dodać kod:

print(df.shape)

# (250, 5)

Dzięki zastosowaniu .shape dowiemy się, że nasz obiekt zawiera 250 wierszy z danymi w 5 seriach.

W trakcie wczytywania danych z plików CSV do DataFrame za pomocą biblioteki Pandas mamy do dyspozycji imponujący zestaw narzędzi. Funkcja pd.read_csv() oferuje ponad 30 parametrów dodatkowych, które umożliwiają precyzyjne dostosowanie procesu wczytywania danych do indywidualnych potrzeb projektu. Te dodatkowe opcje są szczególnie cenne, gdy mamy do czynienia z dużymi, rozbudowanymi zbiorami danych.

Na przykład, możemy kontrolować sposób obsługi brakujących danych za pomocą parametra na_values. Ustalać niestandardowe separatory kolumn przy pomocy sep, lub nawet decydować o tym, które kolumny traktować jako indeksy poprzez index_col. Pełną listę parametrów znajdziesz tutaj: https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html.

Dostęp do danych w DataFrame

W DataFrame mamy wbudowaną możliwość dostępu do danych jako atrybutu obiektu. Operując na powyższym przykładzie możemy wykonać:

print(df.movie_name)
# Otrzymamy listę filmów

print(df.movie_name[0])
# Otrzymamy tytuł filmu na pierwszym miejscu

print(df['movie_name'])
# Tak samo jak w pierwszej linijce, otrzymamy listę filmów

loc i iloc

Powyższy przykład pokazuje, jak prosty może być dostęp do danych w DataFrame, natomiast działanie takie jest także szeroko dostępne w innych typach danych w Python, więc nie jest to nic odkrywczego.

Biblioteka Pandas posiada jednak także specyficzne atrybuty dostępu: loc i iloc.

Wybór na podstawie indeksu, czyli iloc

iloc umożliwia indeksowanie danych na podstawie pozycji, czyli numerów indeksów kolumn i wierszy. Przykładowo, df.iloc[0, 1] zwróci wartość w pierwszym wierszu i drugiej kolumnie. Istotna jest różnica względem wbudowanych funkcji Pythona. Atrybuty loc i iloc są atrybutami row-first, column-second. Poniżej znajdziesz kilka przykład użycia atrybutu iloc.

import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data, index=['X', 'Y', 'Z'])

print(df.iloc[0, 1]) 
# Wynik: 4, dla wiersza 0 kolumny 1 czyli "B"

print(df.iloc[0]) 
# Wynik:
# A    1
# B    4
# C    7
# Name: X, dtype: int64

Odwrócenie kolejności podawania najpierw indeksu wiersza, a następnie kolumny sprawia, że bardzo łatwo otrzymać pełny wiersz danych, natomiast znacznie trudniej otrzymać wartości dla pojedynczej kolumny. Kolumnę z pomocą iloc możemy otrzymać w następujący sposób:

print(df.iloc[:, 0]) 
# Wynik:
# X    1
# Y    2
# Z    3
# Name: A, dtype: int64

Operator : oznacza w Pythonie „wszystko” lub w połączeniu z wartościami, może oznaczać konkretny zakres. Jeśli chcielibyśmy pobrać tylko dwie pierwsze wiersze dla kolumny B możemy wykonać operację:

print(df.iloc[:2, 1])
# Wynik:
# X    4
# Y    5
# Name: B, dtype: int64

Możemy także wykonać takie operacje:

df.iloc[2:3, 1] # Zwróci wiersze 2 i 3 dla kolumny 1
df.iloc[[0, 1, 2], 1] # Zwróci wiersze 1, 2 i 3 dla kolumny 1
df.iloc[-2:, 1] # Zwróci 2 ostatnie wiersze dla kolumny 1

Wybór na podstawie etykiety

loc pozwala na wybór danych na podstawie etykiet, czyli nazw kolumn i indeksów wierszy. Przykładowo, jeśli mamy DataFrame df z kolumnami 'A’, 'B’, 'C’ i indeksem 'X’, 'Y’, możemy użyć df.loc['X', 'A'], aby uzyskać wartość znajdującą się w kolumnie 'A’ i wierszu 'X’.

import pandas as pd

data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
df = pd.DataFrame(data, index=['X', 'Y', 'Z'])

value = df.loc['X', 'A']
print(value)  # Wynik: 1

Możliwe są także następujące operacje z loc:

df.loc[1, 'A'] # Zwróci wartość kolumny A dla wiersza 2
df.loc[:, 'B'] # Zwróci wszystkie wartości kolumny B

Różnice między iloc i loc

Atrybut loc jest wykorzystywany w sytuacjach, gdy chcemy odwołać się do danych za pomocą ich etykiet, czyli nazw kolumn i indeksów wierszy. To także narzędzie, które sprawdza się doskonale w zadaniach analizy danych, gdzie dane są opisane przez zdefiniowane etykiety.

Z kolei atrybut iloc znajduje zastosowanie, gdy zależy nam bardziej na dostępie do danych za pomocą ich pozycji numerycznych. Stosujemy go, gdy chcemy operować na danych, których indeksy są liczbami porządkowymi, a precyzyjne etykiety nie są niezbędne.

Warto w tym miejscu podkreślić różnice w numerowaniu indeksów. Atrybut loc operuje na bazie etykiet indeksów, co oznacza, że włącza ostatni indeks w zakresie, czyli odwołując się do df.loc[1:3], uzyskamy dane od indeksu 1 do 3 włącznie. Z kolei atrybut iloc korzysta z pozycji numerycznych, co oznacza, że zakres df.iloc[1:3] zawiera indeksy od 1 do 2, ale nie włącza 3.

Modyfikacja indeksu

Wybór na podstawie etykiety jest szczególnie użyteczny, ze względu na indeksy, które mogą być etykietami. Indeks danych możemy jednak dowolnie zmieniać przy użyciu funkcji df.set_index(). Wróćmy do naszego wcześniejszego przykładu z listą najlepiej ocenianych filmów anglojęzycznych. Po domyślnym załadowaniu pliku tworzone są indeksy liczbowe, które w poniższym przykładzie zmienimy.

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv')

# Zmiana indeksu na kolumnę movie_name
df_indexed_by_movie_name = df.set_index('movie_name')

# Wyświetlenie kilku pierwszych wierszy DataFrame
print(df_indexed_by_movie_name.head())

Ustawienie indeksu moglibyśmy także wykonać od razu przy wczytywaniu danych z CSV, ale warto pamiętać, że DataFrame z biblioteki Pandas daje możliwość dowolnej zmiany indeksu.

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame z ustaleniem kolumny indeksu
df = pd.read_csv('top_english_movies.csv', index_col='movie_name')
print(df.head())

Warunkowy wybór danych

Niemal magiczną funkcjonalnością jaką daje DataFrame z biblioteki Pandas jest możliwość warunkowego wyboru danych. Przyjdźmy od razu do przykładu korzystającego z wcześniej wczytanej bazy danych filmów.

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv', index_col='movie_name')

# Wybór tylko filmów po 2000 roku
print(df.loc[df.movie_year > 2000])

W wyniku powyższego kodu otrzymamy listę filmów, które spełniają określone kryteria, czyli zostały wyprodukowane po 2000 roku. Dzieje się tak, dzięki zastosowaniu warunku: df.movie_year > 2000. W atrybucie loc możemy także łączyć warunki za pomocą operatora & koniunkcji lub | alternatywy. W następnym przykładzie wybierzmy najlepsze filmy z lat ’90:

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv', index_col='movie_name')

# Wybór tylko filmów z lat '90
print(df.loc[(df.movie_year >= 1990) & (df.movie_year < 2000)].head())

Czy też uważacie, że The Shawshank Redemption to najlepszy film lat ’90? 🙂

Biblioteka Pandas daje jeszcze inne możliwości warunkowego wyboru danych. W kolejnym przykładzie wybierzemy filmy tylko z roku 2000 oraz 1990, dzięki operatorowi isin().

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv', index_col='movie_name')

# Wybór tylko filmów z roku 1990 i 2000
print(df.loc[df.movie_year.isin([2000, 1990])].head())

W śród innych funkcji warunkowych można także wymienić funkcję .notnull() , która pozwala wyeliminować puste wartości, lub odwrotną .isnull().

Modyfikacja danych w DataFrame

Aby przypisać wartość do całej kolumny, możemy wykonać operację:

import pandas as pd

# Wczytanie danych z pliku CSV do DataFrame
df = pd.read_csv('top_english_movies.csv', index_col='movie_name')

df['new_value'] = 'stała wartość'

# Wybór 5 rekordów z nową kolumną
print(df.head())

W taki sposób możemy wyedytować wartości w istniejącej kolumnie, jak i dodać nową kolumnę ze stałą wartością.

Podsumowanie

W tym wpisie poznaliśmy podstawy biblioteki Pandas. W kolejnych wpisach pochylimy się bardziej nad funkcjami przetwarzania i analizy danych z Pandas.

Zachęcam do przeczytania kolejnego wpisu na temat analizy danych w Pandas: Podstawy analizy danych z biblioteką Pandas.