Pandas rozpoznaje, podobnie jak Python, różne typy danych – liczby, ciągle znaków itd. Prawda jest jednak taka, że nie przejmujemy się tym zbytnio, do czasu otrzymania związanego z typami danych błędu. Dopiero wtedy zaczyny dociekać na czym się różnią typy danych i jak je pozamieniać. I dokładnie takie podejście zastosujemy w tej lekcji. Zaczynajmy!

W tej lekcji skorzystamy ze zbioru danych zawierającego informacje o filmach.

import pandas as pd
pd.read_csv('https://analityk.edu.pl/wp-content/uploads/2020/12/film.csv', sep=';', encoding = "ISO-8859-1")

Plik jest już problematyczny od samego początku. Separatorem w tym pliku jest średnik ';', a nie tak jak to zwykle bywa w przypadku plików csv – przecinek oraz został zapisany w standardzie '”ISO-8859-1″. Jest to dość rzadkie. Na ogół pliki CSV są zapisywane w standardzie UTF-8 i ich odczyt nie stanowi problemu.

 Nie będziemy wnikać w szczegóły, jednak warto być świadomym problemów z formatem plików oraz potencjalnych rozwiązań. Idźmy dalej i zajrzyjmy do środka:

Widzimy że pierwszy wiersz w pliku zawiera typ kolumn, tak więc ten wiersz jest interesujący, jednak do skasowania. Ostatnia kolumna jest *Image jest również do skasowania, nie przyda nam się.

# Kasujemy pierwszy wiersz

films = films.drop(0)

# Kasujemy ostatnią kolumnę

films = films.drop(columns=['*Image'])

Zobaczmy jaka jest średnia długość filmu.

films.Length.mean()

Operacja kończy się jednak błędem. Otrzymujemy informację o ' TypeError: can only concatenate str (not „int”) to str'. Świadczy to o problemie z typem danych. Czyli nasza kolumna Length nie jest rozpoznana przez Pandas jako liczby.

Typy danych w Pandas DataFrame

Na początku sprawdźmy jak Pandas widzi nasz zbiór danych. Możemy skorzystać z funkcji info() lub parametru dtypes:

Widzimy że nasz zbiór zawiera trochę wartości pustych, ale przede wszystkim, że wszystkie kolumny są rozpoznane jako typ object.

Python Pandas rozpoznaje następujące typy danych:

Typ danych w Python Pandas DataFrame Odpowiednik w Python
object String (łańcuch znaków)
int64 Integer (liczba całkowita)
float64 Float (liczba rzeczywiste)
bool bool (True lub False)
Category NA
datetime datetime

.

Tak jak widzimy typy danych w Pandas są bardzo podobne do tych znanych nam z Python. Dodatkowo mamy do dyspozycji Category. No ale wróćmy do naszego problemu.

Na kolumnie która została wczytana z pliku jako typ object (czyli zmienna przeznaczona do przechowywania tekstu) próbujemy wykonać operację matematyczną. Tym samym musimy zmienić typ naszej kolumny na taką która pozwoli nam na operacje matematyczne – int64 lub float64.

Zamiana typów danych w Pandas DataFrame

W Pandas mamy kilka możliwości zmiany typu danych. Niektóre z nich już poznaliśmy i zobaczmy ponownie a niektóre będą czymś nowym.

  • to_numeric()

Jest to najprostszy sposób zamiany kolumn, które są rozpoznane jako typ object, a zawierają liczby, na typ danych numeryczny.

films.Length = pd.to_numeric(films.Length)
films.dtypes

Tym samym, widzimy że typ danych kolumny lenght został zamieniony na float64:

A my możemy wykonać operacje matematyczne na tej kolumnie, takie jak policzenie średniej długości trwania filmu w naszej bazie danych.

films.Length.mean()
  • astype()

Funkcja astype() jest troszkę starsza od funkcji to_numeric(), ale za to daje większe możliwości. Funkcja to_numeric, sama dobrała typ danych, ale ograniczała się tylko do zamiany object na liczby. astype() wymaga ręcznego podania typu danych który chcemy osiągnąć ale możemy próbować zamieniać dowolne typy danych na dowolne inne.

films.Popularity = films.Popularity.astype('float64')
  • apply()

Trzecim sposobem, na zmianę typu danych o którym powiemy, jest sposób najbardziej uniwersalny i potężny. Otóż możemy zastosować funkcję apply, która może czytać wartość w jednym formacie, a zwracać ją w zupełnie innych.

Dla przykładu, pod lupę wezmę kolumnę Award. Czyli informację czy dany film dostał nagrodę czy też nie. Zamienie typ tej kolumny na bool, natomiast jeżeli dostał nagrodę (wartość Yes) to wpiszę True. W innym przypadku wpiszę wartość False:

def zamien(wartosc):
    if wartosc == 'No': return False
    if wartosc == 'Yes': return True
    
films.Awards = films.Awards.apply(zamien)
films.dtypes

Rozwiązanie krótkie, czytelne, efektywne. Nasz zbiór wygląda teraz tak:

Lepsze wczytanie pliku CSV

Powyżej zobaczyliśmy jak możemy poczyścić nasz zbiór danych usuwając kolumny, wiersze i nadając odpowiednie typy danych naszym kolumnom. Są to jak najbardziej słuszne rozwiązania. Jednak teraz, kiedy wiemy z jakimi problemami mieliśmy od czynienia, warto zadać sobie pytanie czy nie warto wykonać części z tych operacji na etapie czytania pliku?

Okazuje się że z funkcją read_csv() jest to możliwe korzystając z dodatkowych parametrów takich jak:

  • dtype, który zdefiniuje nam od razu typy kolumn,
  • skiprows, który umożliwi nam ominięcie pierwszego, problematycznego wiersza.
  • usecols, gdzie możemy podać interesujące nas kolumny
  • czy też converters, który umożliwia nam zastosowanie apply

Zobaczmy:

def zamien(wartosc):
    if wartosc == 'No': return False
    if wartosc == 'Yes': return True

films = pd.read_csv('https://analityk.edu.pl/wp-content/uploads/2020/12/film.csv', 
                    sep=';', 
                    encoding = "ISO-8859-1",
                    skiprows=[1],
                    dtype={'Length':'float64', 'Popularity':'float64'},
                    usecols=['Year','Length','Title','Subject','Popularity','Awards'],
                    converters={'Awards':zamien})

Mało tego, dla tych który znają funkcje lambda, możemy uprościć nasz zapis do takiej postaci:

films = pd.read_csv('https://analityk.edu.pl/wp-content/uploads/2020/12/film.csv', 
                    sep=';', 
                    encoding = "ISO-8859-1",
                    skiprows=[1],
                    dtype={'Length':'float64', 'Popularity':'float64'},
                    usecols=['Year','Length','Title','Subject','Popularity','Awards'],
                    converters={'Awards':lambda x: True if x == 'Yes' else False})

Przerażające, ale zrozumiałe. Na pewno nikt to na rozmowie rekrutacyjnej coś takiego zobaczy w Twoim portfolio, nie będzie się pytać czy umiesz wczytać plik w Pandas 😀

Podsumowanie

W tej lekcji zobaczyliśmy jak możemy radzić sobie z różnymi typami danych. Zrobiliśmy to w klasyczny sposób, czyli rozwiązując problemy które nas napotkały.

Jak się również okazało, nasza znajomość i podziw wobec funkcji read_csv() urósł, oraz rozumiemy czemu nie było najmniejszego sensu opisywać tę funkcją w szczegółach na samym początku tutorial, jak to często bywa.

Plik i kody warto zachować, gdyż będziemy z niego korzystać w kolejnych lekcjach. Ale zanim do nich przejdziemy …… ćwiczenie 🙂

Ćwiczenia Pandas

A ćwiczenie z faktu charakteru tej lekcji, są dość specyficzne

  1. Powtórzyć czyszczenie pliku, nie używając opcji funkcji read_csv()
  2. Powrócić do pliku Halloween i sprawdzić z jakimi typami danych mieliśmy tam do czynienia.

Spis treści Pandas Tutorial / Kurs

  1. Pandas – Intro
  2. Pandas – przygotowanie środowiska pracy
  3. Pandas – tworzenie prostego DataFrame
  4. Pandas – odczyt i zapis do pliku
  5. Pandas – podstawowe informacje o DataFrame
  6. Pandas – indeksy oraz funkcja loc
  7. Pandas – maski
  8. Pandas – modyfikacje kolumn
  9. Pandas – funkcja apply
  10. Pandas – typy danych
  11. Pandas – grupowanie z groupby
  12. Pandas – unstack oraz tabele przestawne
  13. Pandas – łączenie zbiorów danych
  14. Pandas – SQL i bazy danych

Facebook Comments