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ą.

Skąd brać dane do projektów data science? Czyli webscraping.

Webscraping – co to takiego?

Jest to proces automatycznego pobierania stron internetowych i wyciągania z nich interesujących nas informacji. Ponieważ dzieje się to automatycznie zajmuje to oczywiście mniej czasu niż gdybyśmy to chcieli zrobić ręcznie.

Od czego zacząć?

Najważniejsze co musimy zrobić chcąc skorzystać z danych umieszczonych na jakiejś stronie to upewnienie się, że jej warunki użytkowania nam na to pozwalają.
Jeśli już mamy taką stronę, której zawartość możęmy wykorzystać musimy się zastanowić jakie dane są nam potrzebne. Nastepnie z pomocą przyjdzie nam opcja Inspect (Zbadaj) w przeglądarce. Pozwoli nam ona w wygodny sposób przejrzeć strukturę HTML.

Kiedy ustalimy strukturę stron, które nas interesują jesteśmy gotowi napisać automat. W Pythonie z pomocą przyjdą nam takie biblioteki jak:

URLOPEN

Jest to funkcja modułu urllib.request, który umożliwia pobieranie stron z danego URL. Korzystamy z niej w bardzo prosty sposób:

page = urlopen("Url którego zawartość chcemy pobrać).read()

W ten sposób w zmiennej page mamy zawartość danej strony.

BEAUTIFULSOUP4

Ta biblioteka ułatwia przechodzenie po strukturze HTML. Na przykład, by wybrać wszystkie punkty danej listy wywołamy coś takiego:

data = BeautifulSoup(html, "lxml")
listelements = data.find_all("li")

Gdy już będziemy mieli dane, to możemy użyć biblioteki pandas, o której już tutaj wspominałam. Pozwala ona analizować dane w bardzo wygodny sposób.

Mogą nam się również przydać wyrażenia regularne i tutaj z przyda nam się operator Re, który również znajdziemy w Pythonie.  Pozwala on między innymi na wyszukiwanie i dopasowywanie tekstów do wzorca.

Kiedy już zdobędziemy dane, wyciągniemy co trzeba, obrobimy by format nam odpowiadał możemy użyć klasy DictWriter aby zapisać je w formacie CSV albo modułu do Sqlite by zapisać dane w bazie.