NumPy, NumPy ale Pandas to dopiero coś

Kiedyś już wspominałam o Pandas czyli bibliotece do Pythona, która umożliwia analizę danych a przy tym robi to bardzo wydajnie oraz jest łatwa i przyjemna w użyciu. Przy tym jest obecnie najpopularniejszą biblioteką do pracy z danymi tabelarycznymi w Pythonie.

W Pandas do przedstawiania danych tabelarycznych stosujemy tzw dataframe czyli dwuwymiarową strukturę, która dostarcza nam zestaw narzędzi do szybkiego przeglądania, analizowania i wizualizowania danych.

W czym Pandas jest lepsze od NumPy?

  • Jednym z powodów jest to, że w NumPy w tabeli mogliśmy mieć wyłącznie dane jednego typu. W Pandas te dane mogą mieć różne typy.
  • Przewagą Pandas jest również obiekt NaN, który umożliwia nam obsługę nie istniejących danych (na przykład pustych niektórych pól w tabeli).
  • Kolejna rzecz to możliwość odwoływania się do wierszy i kolumn nie tylko poprzez numery, ale również poprzez nazwy (label).

Przede mną jeszcze kilka lekcji na temat Pandas, więc na pewno wrócę tutaj z kolejnymi ciekawostkami.

Kolejne fajne rzeczy w NumPy

W zeszłym tygodniu pisałam o tym jak NumPy ułatwia nam życie. Dziś będzie jeszcze troszkę w tym temacie. Co jeszcze fajnego dostarcza nam NumPy? Na przykład wygodnego filtrowania danych. Załóżmy, że mamy jakąś tablicę:

some_numbers = numpy_array([0, 10, 100, 200, 201]);

I chcemy z niej wyciągnąć tylko wartości, które dzielą się przez 100.
W zwykłym Pythonie oczywiście musielibyśmy przejść pętlą przez całą tablicę i po kolei sprawdzać poszczególne wartości. Z pomocą NumPy możemy to zrobić dużo sprawniej. Zapiszemy sobie coś takiego:

divisible_by_one_hundred = (some_numbers % 100)

Ale to tylko krok pośredni. W tablicy divisible_by_one_hundred będziemy mieli obecnie coś takiego:

[false, false, true, true, false]

Co możemy z tym zrobić dalej by uzyskać pożądany wynik? Otóż możemy tablicy divisible_by_one_hundred użyć jako filtra w ten oto sposób:

numbers_divisible_by_one_hundred = some_numbers[divisible_by_one_hundred]

To stworzy nam taką oto tablicę:

[100, 200]

Proste i takie wygodne! Analiza danych w takich warunkach to naprawdę fajna sprawa:)

NumPy – jak ładnie ułatwia nam życie

Załóżmy, że mamy takie oto dane:

Year Number of items Number of another items
2001 100 1000
2002 101 1001
2003 102 1002
2004 103 1003

Wszystko to znajduje się w pliku csv o nazwie data.csv i chcemy je sobie wczytać do jakiejś zmiennej. W czystym Pythonie musimy zrobić coś takiego:

with open('data.csv', 'r') as csvfile:
    reader = csv.reader(csvfile)
    data = []
    for row in reader:
        data.append(row)

Kiedyś już wspominałam o tym, że w ramach zapoznawania się z tematem data science uczę się również NumPy czyli pakietu szeroko stosowanego w przetwarzaniu danych w Pythonie. I tak jakbyśmy chcieli wykorzystać NumPy by uzyskać to samo co powyżej musielibyśmy napisać coś takiego:

import numpy
data = numpy.genfromtxt('data.csv', delimiter=',', dtype="U75")

Dużo mniej kodu prawda?

NumPy pozwala nam od razu z pliku zrobić sobie tablicę. Nie musimy pisać pętli by dane z pliku sobie do tablicy przypisać. Co znaczą te tajemicze ustawienia – delimiter i dtype? Otóż pierwsze z nich to ustawienie znaku którym oddzielane są poszczególne kolumny w naszym pliku. Natomiast drugie to ustawienie które powoduje, że wszystkie wczytywane wartości zostaną zinterpretowane jako 75 bajtowy unicode. Umożliwia nam to wówczas pracę nie tylko z danymi liczbowymi, ale również poprawne wczytanie tekstów.

Kolejna rzecz jaką często robi się przy przetwarzaniu danych to wyciągniecie wartości z wyłącznie jednej kolumny w naszym zbiorze danych.
By zrobić to w czystym Pythonie musimy napisać:

number_of_items = []
for item in data:
    number_of_items.append(data[1])

Natomiast korzystając z NumPy:

number_of_items = data[:,0:1]

Podobnie na przykład możemy z pomocą NumPy wyciągnąć prosto wartości 2 i 3 kolumny tylko dla 1 i 2 wiersza. Robimy to w następujący sposób:

number_of_items = data[1:2,0:1]

Notacja z dwukropkiem jest również w czystym Pythonie, ale nie daje nam aż takich możliwości. Pozwala na wyciągniecie zakresu pewnych wartości. Przykładowo

otherdata[a:b]

zwróci nam wartości z tablicy jednowymiarowej other_data o indeksach od a włącznie do b wyłącznie. Z kolei jeśli zapiszemy:

otherdata[a:]

zwróci nam wartości o indeksach zaczynających się od a włącznie.
Tymczasem:

otherdata[:b]

zwróci nam wartości o indeksach od 0 do b wyłącznie.

Gdzie jestem i jak daleko mi do celu:)

Mijają dwa miesiące od początku tegorocznej edycji konkursu „Daj się poznać” więc może czas wreszcie zatrzymać się i podsumować co się do tej pory udało bądź nie udało. Na pewno muszę przyznać, że jest inaczej niż rok temu. Z jednej strony łatwiej a z drugiej – trudniej:)
Dlaczego?

Łatwiej, ponieważ przecież celem w tym roku nie było to, żeby przebić swój zeszłoroczny wynik (drugie miejsce), bo jest to przecież, obiektywnie rzecz biorąc, mało prawdopodobne. Bardziej chodzi mi o zyskanie widoczności w sieci w nowych dla mnie obszarach takich jak właśnie data science czy Python.

A trudniej, bo temat jaki wybrałam w tym roku jest dużo bardziej obszerny niż rok temu. Cóż to było napisać apkę w Androidzie w porównaniu ze zgłębieniem całkiem nowego języka jakim jest Python plus biblioteki typu NumPy i Pandas a jeszcze do tego statystyka:) Jest tego trochę, prawda? Co więcej – tym razem projekt na „Daj się poznać” nie jest jedyną rzeczą jaka mnie pochłania po pracy – z technicznych rzeczy zajmuję się jeszcze nauką Javy, doskonaleniem JavaScriptu (bo mało go używam na codzień). Po co? No cóż, o tym to może w przyszłości jeszcze napiszę;) Tymczasem trzymajcie kciuki!!

Jeśli zatem chodzi o konkurs jestem na dobrej drodze, ponieważ kontynuuje kurs na Dataquest w ścieżce Data Scientist a tak wygląda mój postęp:
Postęp

Jak widać zatem – jeszcze bardzo długa droga przede mną. Ale również długi weekend – więc mam nadzieję, że co nieco nadrobię:)

Pewne jest, że kursu nie skończę przed końcem maja, ale jest szansa na rozwiązanie tego zadania, które było częścią mojego celu, czyli: Partly Sunny with a Chance of Hashtags. Mam również nadzieję, że jeszcze uda mi się przyjrzeć „żywym” danym na Twitterze właśnie w związku z pogodą.

Pierwszy commit;) – Jupyter Notebook

W ostatnim czasie udało mi się przerobić całkiem fajny tutorial na Kaggle.com, który uczy podstaw machine learning na przykładzie pasażerów Titanica i przewidywania, którzy mieli szansę na przetrwanie. Tutorial nazywa się Titanic: Machine Learning from Disaster i pozwala on na przejście całego procesu od przetworzenia zbioru danych do uzyskania wyników, które możemy wysłać na serwer Kaggle w celu zrobienia sobie portfolio.

Ponieważ moim celem w ramach tegorocznego Daj się poznać jest właśnie wrzucenie swoich właśnych „prognoz” na Kaggle do zadania „Partly Sunny with a Chance of Hashtags” taki tutorial bardzo mi pomógł w zrozumieniu co i jak po kolei. Jest tam jednak parę rzeczy, które muszę bardziej zgłębić, by wiedzieć co robię a nie tylko odtwarzać. Jednak w tym świetnie pomaga mi uczenie się na Dataquest o którym już tutaj wspominałam.

Po przerobieniu tutoriala z Titanica moim pierwszym krokiem było przeniesienie instrukcji z tutoriala do notesu Jupyter aby później móc na tym pracować już moim zbiorem danych. Okazało się jednak, że to nie było takie proste, ponieważ po pierwsze po instrukcji:

predictions[predictions > .5] = 1
predictions[predictions <=.5] = 0

dostałam informację: „FutureWarning: in the future, boolean array-likes will be handled as a boolean array index app.launch_new_instance()” Na szczęście to póki co ostrzeżenie, więc nie szukałam w tym momencie rozwiązania dla tego problemu.
Gorzej było, gdy po instrukcji:

alg = LogisticRegression(random_state=1)

pojawiło się:

NameError Traceback (most recent call last)
in ()
----> 1 alg = LogisticRegression(random_state=1)

NameError: name 'LogisticRegression' is not defined

Na szczęście okazało się, że wystarczy instrukcję zamienić na:

alg = linear_model.LogisticRegression(random_state=1)

Jednak w tutorialu nic takiego potrzebne nie było;) No ale na szczęście wszystko ostatecznie poszło szybko i sprawnie. Tak więc krok po kroku posuwam się coraz dalej. Jednak już wiem, że temat Data science jest tak ogromny, iż jeśli nie zwiększę ilości czasu jaki mu poświęcam, zgłębienie go zajmie mi dłużej niż bym chciałą. Ale nie przeszkadza mi to zbytnio, bo jest to bardzo ciekawe!

No i udało się też wrzucić wreszcie coś sensownego do Gita – czyli mój Jupyter Notebook z póki co rozwiązaniem do kwestii Titanica.