Analiza danych i uczenie maszynowe w Python

Autor notebooka: Jakub Nowacki.

Kolekcje

Python posiada wiele wbudowanych typów bardzo przydatnych do pracy z danymi.

Krotki (tuple)

Krotka jest uporządkowaną sekwencja obiektów, która jest niezmienna (immutable). Krotkę definiujemy za pomocą nawiasu okrągłego lub komendy tuple.


In [1]:
t = (1, '2', 3.0)
t


Out[1]:
(1, '2', 3.0)

Przykład operacji na krotkach:


In [3]:
# Pobranie elementu
t[0]


Out[3]:
1

In [2]:
# Rozpakowywanie krotki
a, b, c = t
a, b, c


Out[2]:
(1, '2', 3.0)

In [4]:
# Nie możemy zmienić krotki ale możemy np złożyć dwie krotki co utworzy nową krotkę
t+(4,)


Out[4]:
(1, '2', 3.0, 4)

Krotki można też przecinać (slice) wyciągając tylko pewne elementy:


In [5]:
t = (1, 2, 3, 4, 5)
print(t[:3]) # do 3
print(t[1:4]) # od 1 do 4
print(t[3:]) # od 3 do końca
print(t[::2]) # co 2 
print(t[-1]) # ostatni i ostatni element
a, b = 1, 4
print(t[slice(a,b)]) # definiowanie za pomocą komendy
print(t[a:b]) # to samo


(1, 2, 3)
(2, 3, 4)
(4, 5)
(1, 3, 5)
5
(2, 3, 4)
(2, 3, 4)

Lista

Podobnie do krotki jest to typ opisujący sekwencje, ale tym razem może być zmieniany, np. możemy do listy obiekty dodawać lub je usuwać. Listę tworzymy za pomocą nawiasów kwadratowych lub komendy list:


In [6]:
l = [1, '2', 3.0]
l


Out[6]:
[1, '2', 3.0]

Operacje na listach:


In [7]:
l = [1, '2', 3.0]

# Pobranie elementu
l[1]


Out[7]:
'2'

In [8]:
# Dodanie elementu
l.append(4)
l


Out[8]:
[1, '2', 3.0, 4]

In [9]:
# Usunięcie konkretnego elemetu
l.remove(4)
l


Out[9]:
[1, '2', 3.0]

In [10]:
# Pobranie elementu ostatniego (można tez przekazać indeks)
p = l.pop()
p, l


Out[10]:
(3.0, [1, '2'])

In [11]:
# Rozszeżenie za pomocą sekwencji
l.extend((5,6))
l


Out[11]:
[1, '2', 5, 6]

In [12]:
# Odwracanie w miejscu
print(l)
l.reverse()
l


[1, '2', 5, 6]
Out[12]:
[6, 5, '2', 1]

In [13]:
# Sortowanie w miejscu
print(l)
l.sort()
l


[6, 5, '2', 1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-133a55973d6c> in <module>()
      1 # Sortowanie w miejscu
      2 print(l)
----> 3 l.sort()
      4 l

TypeError: '<' not supported between instances of 'str' and 'int'

In [14]:
# Sortowanie funkcyjne
posortowana = sorted(l)
print(posortowana)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-243bd0228d05> in <module>()
      1 # Sortowanie funkcyjne
----> 2 posortowana = sorted(l)
      3 print(posortowana)

TypeError: '<' not supported between instances of 'str' and 'int'

In [15]:
# Przecięcie nadal działa
l[2:4]


Out[15]:
['2', 1]

In [16]:
# Można też stworzyć listę list (macierz?)
m = [[1,2],[3,4]]
m


Out[16]:
[[1, 2], [3, 4]]

In [17]:
# Najpierw adresujemy wiersz potem kolumnę
m[1][0]


Out[17]:
3

In [18]:
# Zarówno krotka jak i lista ma poniższe właściwości
print(len(l), len(m)) # Długość
print([1,2]+[3,4]) # Złożenie
print(1 in [1,2]) # Przynależność
for i in [1,2,3]: # Można po nich iterować
    print(i)


4 2
[1, 2, 3, 4]
True
1
2
3

Zbiór

Zbiór jest obiektem odwzorowujący zbiór matematyczny, w którym wszystkie elementy są unikalne. Zbiór zachowuje się podobnie do krotki ale nie trzyma pozycji elementu. Zbiory są głównie wykorzystywane do zbierania elementów unikalnych i sprawdzania przynależności, gdyż dla zbioru jest to operacja dużo szybsza niż dla listy czy krotki, zobacz wiki Pythona. Krotkę definiujemy używając nawiasów klamrowych lub funkcji set:


In [ ]:
s = {1, 2, 3}
s

Operacje na zbiorach:


In [ ]:
# Można dodac element
s.add(4)
s

In [ ]:
# ... ale zawsze zbiór pozostanie unikalny
s.add(4)
s.add(4)
s.add(3)
s

In [ ]:
# Usuwanie elemntu
s.remove(4)
s

In [ ]:
# Zbór nie ma indeksu
s[1]

In [19]:
# Operacje na zbiorach
print({1,2} - {2,3}) # Różnica
print({1,2} | {2,3}) # Suma
print({1,2} & {2,3}) # Iloczyn
print({1,2} ^ {2,3}) # Różnica symetryczna


{1}
{1, 2, 3}
{2}
{1, 3}

In [ ]:
# Podobnie, zbiór ma poniższe właściwości
print(len(s)) # Długość
print(1 in s) # Przynależność
for i in s: # Można po nim iterować
    print(i)
print(s+{3,4}) # Ale już nie ma złożenia, są za to operacje na zbiorach

Słownik

Słownik (dictionary) jest typem podobnym do listy ale zamiast bycia indeksowanym pozycją liczbową, jest indeksowany kluczami. Słownik tworzymy używając nawiasów klamrowych lub funkcją dict:


In [25]:
my_dict = {'wiek': 10, 'wiek': 20, 'imie': 'José', 'nazwisko': 'Jiménez'}
my_dict.values()


Out[25]:
dict_values([20, 'José', 'Jiménez'])

In [ ]:
# ... lub ...
dict([(1,'a'), ('2', 3.0)])

Operacje na słowniku:


In [ ]:
# Pobieranie wartości
print(d[1])
print(d['2'])
print(d[5]) # Błąd bo klucza nie ma

In [ ]:
# Można użyc metody 'get' żeby pobrać wartość lub, jak jej nie ma, zastąpić ją standardową
d.get(5, 'niema')

In [ ]:
# Zmiana wartości klucza
d[1] = 5
d

In [ ]:
# Lista kluczy
d.keys()

In [ ]:
# Lista wartości
d.values()

In [ ]:
# Lista par klucz-wartość
d.items()

In [ ]:
# Można sprawdzić czy jest klucz
print(1 in d)

In [ ]:
# Słownik ma poniższe właściwosći
print(len(d)) # Długość
print(1 in d) # Przynależność (obecnośc klucza)
for i in d: # Można iterować po kluczach
    print(i, d[i])
for k, v in d.items(): # Lub po parach klucz-wartość
    print(k, v)

Wyrażenia generujące

Python ma wygodny mechanizm generowania kolekcji używając wyrażeń generujących. Wyrażenia są złożeniem nawiasów tworzących kolekcje z pętlą for i wyrażeniem if (opcjonalne). Przykłady:


In [ ]:
# Generujemy listę nazw z indeksami
["nazwa-{}".format(i) for i in range(5)]

In [ ]:
# ... ale tylko parzystymi (i zerem) ...
["nazwa-{}".format(i) for i in range(5) if i % 2 == 0]

In [ ]:
# ... a może zbór...
{"nazwa-{}".format(i) for i in range(5) if i % 2 == 0}

In [ ]:
# ... lub słownik...
{"nazwa-{}".format(i):i for i in range(5) if i % 2 == 0}

Zadanie

  1. Wygeneruj listę 20 zmiennych całkowitych od 5 do 25.
  2. Wypisz wszystkie wartości w formie tekstu w postaci: Wartość <indeks> to <wartość>.
  3. Wygeneruj 50 całkowitych wartości losowych z zakresu [1,10]; (podpowiedź).
  4. ★ Wypisz wszystkie unikalne wartości wśród wartości losowych.
  5. ★ Policz ile razy pojawiła się dana wartość.

In [26]:
my_list = list(range(5, 25))


Out[26]:
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

In [40]:
[f'Wartość {my_list.index(e)} to {e}' for e in my_list]


Out[40]:
['Wartość 0 to 5',
 'Wartość 1 to 6',
 'Wartość 2 to 7',
 'Wartość 3 to 8',
 'Wartość 4 to 9',
 'Wartość 5 to 10',
 'Wartość 6 to 11',
 'Wartość 7 to 12',
 'Wartość 8 to 13',
 'Wartość 9 to 14',
 'Wartość 10 to 15',
 'Wartość 11 to 16',
 'Wartość 12 to 17',
 'Wartość 13 to 18',
 'Wartość 14 to 19',
 'Wartość 15 to 20',
 'Wartość 16 to 21',
 'Wartość 17 to 22',
 'Wartość 18 to 23',
 'Wartość 19 to 24']

In [48]:
import random

random_numbers = [random.randint(1, 10) for a in range(1, 50)]

counter = dict()
for e in random_numbers:
    if not e in counter:
        counter[e] = 0
    else:
        counter[e] += 1

counter


Out[48]:
{1: 4, 2: 4, 3: 7, 4: 3, 5: 3, 6: 2, 7: 3, 8: 8, 9: 3, 10: 2}

In [51]:
import random
from collections import Counter

random_numbers = [random.randint(1, 10) for a in range(1, 50)]

counter = Counter(random_numbers)
counter.most_common(5)


Out[51]:
[(7, 12), (4, 8), (9, 6), (1, 5), (2, 4)]

In [ ]: