Hlavní navigace

Knihovna Pandas: práce s datovými řadami (series)

10. 12. 2020
Doba čtení: 35 minut

Sdílet

Ve třetím článku o knihovně Pandas se budeme primárně zabývat datovými řadami, tj. typem, který je reprezentován třídou Series. Jedná se o jeden ze základních typů (společně s datovými rámci), na nichž je celá knihovna Pandas postavena.

Obsah

1. Knihovna Pandas: práce s datovými řadami (series)

2. Konstrukce datové řady

3. Počet prvků v datové řadě versus specifikace indexů

4. Konstrukce datové řady ze slovníku, vliv pořadí klíčů

5. Vytvoření nové datové řady z řady stávající – výběr prvků na základě jejich indexů

6. Základní statistické informace o prvcích uložených v datové řadě

7. Vektorové operace nad všemi prvky datové řady

8. Výběr prvků z datové řady na základě podmínky

9. Konverze mezi různými datovými typy datové řady

10. Použití hodnot None, resp. numpy.nan

11. Vykreslení hodnot prvků z datové řady formou grafu

12. Liniový (spojnicový) graf a graf s vyplněnou plochou pod liniovým grafem

13. Vertikální i horizontální sloupcové grafy

14. Graf s KDE (Kernel density estimation)

15. Koláčový diagram

16. Data obsahující šum

17. Vyhlazení průběhu na grafu

18. Graf s několika průběhy získanými z datové řady, použití podgrafů

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Knihovna Pandas: práce s datovými řadami (series)

Ve druhém článku o knihovně Pandas jsme se seznámili s tabulkou nových datových typů, které jsou v rámci této knihovny do Pythonu přidány:

# Datový typ Stručný popis
1 Series odvozeno od 1D pole knihovny Numpy, rozšířeno o popis os
2 DataFrame reprezentace dat uložených do tabulky s popisem os (sloupců, řádků)
     
3 DatetimeTZDtype datum s přidanou informací o časové zóně
4 PeriodDtype reprezentace časové periody (offsetu)
5 IntervalDtype reprezentace numerického intervalu (odvozeno od dalších typů, například int64 atd.)
6 Int8Dtype typ int8 rozšířený pro podporu hodnoty pandas.NA
7 Int16Dtype typ int16 rozšířený pro podporu hodnoty pandas.NA
8 Int32Dtype typ int32 rozšířený pro podporu hodnoty pandas.NA
9 Int64Dtype typ int64 rozšířený pro podporu hodnoty pandas.NA
10 UInt8Dtype typ uint8 rozšířený pro podporu hodnoty pandas.NA
11 UInt16Dtype typ uint16 rozšířený pro podporu hodnoty pandas.NA
12 UInt32Dtype typ uint32 rozšířený pro podporu hodnoty pandas.NA
13 UInt64Dtype typ uint64 rozšířený pro podporu hodnoty pandas.NA
14 CategoricalDtype kategorie (odvozeno od jazyka R, bude popsáno příště)
15 SparseDtype použito pro ukládání řídkých polí (bude popsáno příště)
16 StringDtype rozšíření řetězců; prozatím ve fázi experimentálního rozšíření
17 BooleanDtype rozšíření pravdivostního typu; prozatím ve fázi experimentálního rozšíření

Základním stavebním kamenem knihovny Pandas je přitom typ Series (datová řada), který zapouzdřuje jednodimenzionální pole z knihovny Numpy. Datová řada představuje uspořádaný sloupec údajů, které mají shodný typ (například int64 nebo float64 atd.), přičemž každému prvku je přiřazen index. Nemusí se přitom jednat o celé číslo, protože indexem mohou být i řetězce atd. – což je mimochodem velmi užitečné, jak uvidíme dále. Instance třídy Series mají několik užitečných atributů:

# Atribut Stručný popis
1 index indexy prvků v řadě
2 values hodnoty prvků ve formě 1D pole
3 size počet prvků v řadě
4 name jméno řady (pokud je specifikováno)
5 dtype typ prvků uložených v datové řadě
6 hasnans test, zda je nějaký prvek roven NaN

Dále instance této třídy podporují několik desítek metod; s některými z nich se seznámíme v dalším textu.

2. Konstrukce datové řady

Nejprve si ukážeme, jakým způsobem se datové řady vytváří. Nejjednodušší je situace ve chvíli, kdy jsou hodnoty, které se mají převést na datovou řadu, připraveny ve formě seznamů nebo n-tic (ve smyslu základních datových typů programovacího jazyka Python). Z takto připravených hodnot se datová řada připraví přímočaře, a to konstruktorem pandas.Series. V dalším příkladu předáváme konstruktoru n-tici, proto se používá dvojice kulatých závorek:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((1, 2, 3, 4, 5, 6))
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

Povšimněte si, že v tomto případě jsou indexy prvků v datové řadě dopočteny automaticky (první sloupec ve výpisu). Současně se uloží i informace, že index je tvořen generátorem RangeIndex:

Series:
0    1
1    2
2    3
3    4
4    5
5    6
dtype: int64
 
Index:
RangeIndex(start=0, stop=6, step=1)
 
Values:
[1 2 3 4 5 6]
 

Specifikovat je možné i indexy jednotlivých prvků. Ty se předávají ve druhém parametru konstruktoru pandas.Series:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(('a', 'b', 'c', 'd', 'e', 'f'), (1, 2, 3, 4, 5, 6))
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

Výsledek bude vypadat takto:

Series:
1    a
2    b
3    c
4    d
5    e
6    f
dtype: object
 
Index:
Int64Index([1, 2, 3, 4, 5, 6], dtype='int64')
 
Values:
['a' 'b' 'c' 'd' 'e' 'f']
 

3. Počet prvků v datové řadě versus specifikace indexů

Při konstrukci datové řady je zapotřebí zaručit, že počet prvků bude odpovídat počtu zadaných indexů (samozřejmě za předpokladu, že indexy explicitně potřebujeme nastavit). Například následující příklad je plně funkční, protože počet prvků (1, 2, 3, 4, 5 a 6) přesně odpovídá počtu zadaných indexů, tedy ‚a‘, ‚b‘, ‚c‘, ‚d‘, ‚e‘ a ‚f‘:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

Výsledek:

Series:
a    1
b    2
c    3
d    4
e    5
f    6
dtype: int64
 
Index:
Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object')
 
Values:
[1 2 3 4 5 6]
 

Naproti tomu další příklad skončí s chybou, protože počet prvků a indexů si neodpovídá:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(range(1, 10), ('a', 'b', 'c'))
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

Chyba:

Traceback (most recent call last):
  File "series_04.py", line 6, in <;module>
    s = pandas.Series(range(1, 10), ('a', 'b', 'c'))
  File "/home/ptisnovs/.local/lib/python3.6/site-packages/pandas/core/series.py", line 314, in __init__
    f"Length of passed values is {len(data)}, "
ValueError: Length of passed values is 9, index implies 3.

Totéž ovšem platí i naopak, pokud bude počet indexů větší než počet prvků:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(range(1, 3), ('a', 'b', 'c', 'd', 'e', 'f', 'g'))
 
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

S chybou:

Traceback (most recent call last):
  File "series_04.py", line 6, in <;module>
    s = pandas.Series(range(1, 3), ('a', 'b', 'c', 'd', 'e', 'f', 'g'))
  File "/home/ptisnovs/.local/lib/python3.6/site-packages/pandas/core/series.py", line 314, in __init__
    f"Length of passed values is {len(data)}, "
ValueError: Length of passed values is 2, index implies 7.

4. Konstrukce datové řady ze slovníku, vliv pořadí klíčů

Poměrně často, zvláště pokud jsou datové řady tvořeny relativně malým počtem prvků (statisíce až miliony prvků), je možné řadu i s indexy vytvořit přímo ze slovníku (dictionary). Důležité přitom je, že je zachováno pořadí prvků ze slovníku (což je nová vlastnost kodifikovaná v Pythonu 3.8). Příklad použití:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
input_data = {
        "a": 1,
        "b": 2,
        "c": 3,
        "d": 4,
        "e": 5,
        "f": 6,
        }
 
print("Input data:")
print(input_data)
print()
 
s = pandas.Series(input_data)
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

S výsledkem (povšimněte si pořadí prvků ve výsledné datové řadě):

Input data:
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
 
Series:
a    1
b    2
c    3
d    4
e    5
f    6
dtype: int64
 
Index:
Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object')
 
Values:
[1 2 3 4 5 6]
 

Prvky ve vstupním slovníku můžeme prohodit:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
input_data = {
        "f": 6,
        "e": 5,
        "d": 4,
        "c": 3,
        "b": 2,
        "a": 1,
        }
 
print("Input data:")
print(input_data)
print()
 
s = pandas.Series(input_data)
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

Tato změna se projeví i v pořadí prvků ve výsledné datové řadě:

Input data:
{'f': 6, 'e': 5, 'd': 4, 'c': 3, 'b': 2, 'a': 1}
 
Series:
f    6
e    5
d    4
c    3
b    2
a    1
dtype: int64
 
Index:
Index(['f', 'e', 'd', 'c', 'b', 'a'], dtype='object')
 
Values:
[6 5 4 3 2 1]
 

Nic nám ovšem nebrání použít i zpětně kompatibilní datovou strukturu OrderedDict, kterou lze použít takto:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
from collections import OrderedDict
 
input_data = OrderedDict()
 
input_data["f"] = 6
input_data["e"] = 5
input_data["d"] = 4
input_data["c"] = 3
input_data["b"] = 2
input_data["a"] = 1
 
print("Input data:")
print(input_data)
print()
 
s = pandas.Series(input_data)
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

S tímto (očekávaným) výsledkem:

Input data:
OrderedDict([('f', 6), ('e', 5), ('d', 4), ('c', 3), ('b', 2), ('a', 1)])
 
Series:
f    6
e    5
d    4
c    3
b    2
a    1
dtype: int64
 
Index:
Index(['f', 'e', 'd', 'c', 'b', 'a'], dtype='object')
 
Values:
[6 5 4 3 2 1]
 

5. Vytvoření nové datové řady z řady stávající – výběr prvků na základě jejich indexů

Datovou řadu je možné vytvořit z řady již existující, a to výběrem indexů těch prvků, které mají být přidány do nové řady. Podobně je možné změnit (mutovat) stávající datovou řadu. Pro oba zmíněné účely se používá metoda nazvaná pandas.Series.reindex, které se předá seznam, popř. pole indexů vybíraných prvků. Samozřejmě nám nic nebrání v tom, aby se některé prvky opakovaly a jiné naopak nebyly použity vůbec:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()
 
s = s.reindex(['d', 'a', 'b', 'c', 'd', 'a', 'a', 'a'])
 
print("Reindexed:")
print()
 
print("Series:")
print(s)
print()
 
print("Index:")
print(s.index)
print()
 
print("Values:")
print(s.values)
print()

S výsledkem:

Series:
a    1
b    2
c    3
d    4
e    5
f    6
dtype: int64
 
Index:
Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object')
 
Values:
[1 2 3 4 5 6]
 
Reindexed:
 
Series:
d    4
a    1
b    2
c    3
d    4
a    1
a    1
a    1
dtype: int64
 
Index:
Index(['d', 'a', 'b', 'c', 'd', 'a', 'a', 'a'], dtype='object')
 
Values:
[4 1 2 3 4 1 1 1]
 
Poznámka: možnosti nabízené touto metodou jsou ve skutečnosti mnohem větší a seznámíme se s nimi v souvislosti se zpracováním naměřených či jinak získaných reálných dat.

6. Základní statistické informace o prvcích uložených v datové řadě

Z datové řady, pochopitelně za předpokladu, že obsahuje numerické hodnoty, lze získat i většinu základních statistických informací – tedy součet prvků, jejich součin, minimální hodnotu, maximální hodnotu, průměrnou hodnotu, medián, kvantil, směrodatnou odchylku atd. K tomuto účelu se používají metody objektu Series, jejichž názvy jsou v oblasti statisticky zavedené:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print("sum", s.sum(), sep="\t")
print("prod", s.prod(), sep="\t")
print("min", s.min(), sep="\t")
print("max", s.max(), sep="\t")
print("median", s.median(), sep="\t")
print("std", s.std(), sep="\t")
print("var", s.var(), sep="\t")
print("quantile", s.quantile(0.01), sep="\t")

Výsledek:

sum             21
prod            720
min             1
max             6
median          3.5
std             1.8708286933869707
var             3.5
quantile        1.05

Užitečné je, že pokud je nějaká hodnota v datové řadě vynechána, výpočty ji přeskočí – tudíž není vyhozena výjimka atd. Pandas se v tomto ohledu tedy chová podobně, jako výpočty v programovacím jazyku R:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((1, 2, None, 4, 5, 6), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print("sum", s.sum(), sep="\t")
print("prod", s.prod(), sep="\t")
print("min", s.min(), sep="\t")
print("max", s.max(), sep="\t")
print("median", s.median(), sep="\t")
print("std", s.std(), sep="\t")
print("var", s.var(), sep="\t")
print("quantile", s.quantile(0.01), sep="\t")

Výsledky:

sum      18.0
prod     240.0
min      1.0
max      6.0
median   4.0
std      2.073644135332772
var      4.3
quantile 1.04

7. Vektorové operace nad všemi prvky datové řady

Třída pandas.Series kromě dalších věcí přetěžuje některé operátory programovacího jazyka Python takovým způsobem, aby bylo například možné sečíst odpovídající prvky ze dvou datových řad, popř. aby se ke každému prvky řady přičetla určitá skalární konstanta. Ukažme si několik příkladů. Nejdříve kombinaci datové řady a skalární hodnoty:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print(s1 + 10)
print(s1 - 10)
print(s1 * 10)
print(s1 / 10)
 
print(s1 % 2)

S výsledky:

a    11
b    12
c    13
d    14
e    15
f    16
dtype: int64
a   -9
b   -8
c   -7
d   -6
e   -5
f   -4
dtype: int64
a    10
b    20
c    30
d    40
e    50
f    60
dtype: int64
a    0.1
b    0.2
c    0.3
d    0.4
e    0.5
f    0.6
dtype: float64
a    1
b    0
c    1
d    0
e    1
f    0
dtype: int64

Vynásobení všech prvků konstantou s úpravou datové řady:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
s1 = s1 * 2
 
print(s1)

Dtto, ale se zkráceným zápisem:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
s1 *= 2
 
print(s1)

Použít je možné i relační operátory. Výsledkem bude nová datová řada obsahující hodnoty True a False:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print(s1 > 3)
print(s1 < 3)
print(s1 % 2 == 0)

Výsledek by měl vypadat následovně:

a    False
b    False
c    False
d     True
e     True
f     True
dtype: bool
a     True
b     True
c    False
d    False
e    False
f    False
dtype: bool
a    False
b     True
c    False
d     True
e    False
f     True
dtype: bool

Podporovány jsou i hodnoty None a NA, které se vyhodnotí na False:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series((1, 2, None, 4, 5, 6), ('a', 'b', 'c', 'd', 'e', 'f'))
 
print(s1 > 3)
print(s1 < 3)
print(s1 % 2 == 0)

S výsledky:

a    False
b    False
c    False
d     True
e     True
f     True
dtype: bool
a     True
b     True
c    False
d    False
e    False
f    False
dtype: bool
a    False
b     True
c    False
d     True
e    False
f     True
dtype: bool

Podobné operace lze provádět i na dvojicí datových řad za předpokladu, že obsahují shodné indexy prvků:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7))
s2 = pandas.Series(np.repeat(100, 6))
 
print(s1 + s2)
print(s1 - s2)
print(s1 * s2)
print(s1 / s2)
print(s1 > s2)
print(s1 < s2)

Výsledky mohou v tomto případě vypadat následovně:

0    101
1    102
2    103
3    104
4    105
5    106
dtype: int64
0   -99
1   -98
2   -97
3   -96
4   -95
5   -94
dtype: int64
0    100
1    200
2    300
3    400
4    500
5    600
dtype: int64
0    0.01
1    0.02
2    0.03
3    0.04
4    0.05
5    0.06
dtype: float64
0    False
1    False
2    False
3    False
4    False
5    False
dtype: bool
0    True
1    True
2    True
3    True
4    True
5    True
dtype: bool

Další podobně koncipované operace, tentokrát s uložením výsledků:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7))
s2 = pandas.Series(np.repeat(100, 6))
 
print(s1)
 
s1 += s2
print(s1)
 
s1 *= s2
print(s1)

8. Výběr prvků z datové řady na základě podmínky

Knihovna Pandas (přesněji řečeno knihovna Numpy volaná přes Pandas) nám dále umožňuje výběr prvků z datové řady na základě vyhodnocení podmínky pro každý prvek. V tomto případě je nutné podmínku zapsat do hranatých (indexových) závorek. Pokud se podmínka vyhodnotí na True, bude prvek použit ve výsledku, v opačném případě bude zahozen. Vybírat tedy můžeme prvky menší nebo větší než nějaká hodnota, prvky dělitelné dvěma atd.:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7))
s2 = pandas.Series(range(50))
 
print(s1[s1<3])
print(s1[s1>3])
 
print(s2[s2 % 2 == 0])
print(s2[s2 % 2 != 0])
 
print(s2[s2 % 3 == 0])

Výsledky:

0    1
1    2
dtype: int64
3    4
4    5
5    6
dtype: int64
0      0
2      2
4      4
6      6
8      8
10    10
12    12
14    14
16    16
18    18
20    20
22    22
24    24
26    26
28    28
30    30
32    32
34    34
36    36
38    38
40    40
42    42
44    44
46    46
48    48
dtype: int64
1      1
3      3
5      5
7      7
9      9
11    11
13    13
15    15
17    17
19    19
21    21
23    23
25    25
27    27
29    29
31    31
33    33
35    35
37    37
39    39
41    41
43    43
45    45
47    47
49    49
dtype: int64
0      0
3      3
6      6
9      9
12    12
15    15
18    18
21    21
24    24
27    27
30    30
33    33
36    36
39    39
42    42
45    45
48    48
dtype: int64

Nic nám ovšem nebrání provádět výběr na základě logické operace aplikované na odlišnou datovou řadu, což je ukázáno v dalším příkladu: prvky z první řady s1 jsou vybírány na základě vyhodnocení podmínky pro prvky řady s2:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
 
s1 = pandas.Series(range(1, 7))
s2 = pandas.Series(range(-3, 3))
 
print(s1[s2 >= 0])
print(s1[s2 < 0])
print(s1[s2 != 0])

Nyní by měly výsledky vypadat takto:

3    4
4    5
5    6
dtype: int64
0    1
1    2
2    3
dtype: int64
0    1
1    2
2    3
4    5
5    6
dtype: int64

9. Konverze mezi různými datovými typy datové řady

Často se setkáme i s nutností konvertovat hodnoty uložené do datové řady tak, aby byl interně použit určitý specifický datový typ. Příkladem může být import dat, provedení nějaké operace s těmito daty (výpočet atd.) a následné uložení dat do jiného formátu, přičemž například výpočty vyžadují použití datového typu float64 atd. Pro přetypování se používá metoda astype, které se předá výsledný datový typ (i ve formátu řetězce):

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100, 200, 300, 400, 500, 600))
print(s.dtypes)
print(s)
print()
 
s = s.astype('int32')
print(s.dtypes)
print(s)
print()
 
s =s.astype('int8')
print(s.dtypes)
print(s)

Po spuštění tohoto příkladu je patrné, že se hodnoty v celé datové řadě skutečně zkonvertovaly:

int64
0    100
1    200
2    300
3    400
4    500
5    600
dtype: int64
 
int32
0    100
1    200
2    300
3    400
4    500
5    600
dtype: int32

Převod na typ int8 vede (pochopitelně) ke ztrátě informace:

int8
0    100
1    -56
2     44
3   -112
4    -12
5     88
dtype: int8

Taktéž je možné využít automatickou konverzi na ten nejlepší datový typ, což je ukázáno na následujícím příkladu, kdy se datová řada obsahující hodnoty float32 převede na typ Int64. Pro automatickou konverzi se používá metoda convert_dtypes:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100, 200, 300, 400, 500, 600), dtype="float32")
print(s.dtypes)
print(s)
print()
 
s = s.convert_dtypes()
print(s.dtypes)
print(s)
print()

S následujícím výsledkem:

float32
0    100.0
1    200.0
2    300.0
3    400.0
4    500.0
5    600.0
dtype: float32
 
Int64
0    100
1    200
2    300
3    400
4    500
5    600
dtype: Int64

Dtto pro datovou řadu obsahující obecné objekty:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100, 200, 300, 400, 500, 600), dtype="O")
print(s.dtypes)
print(s)
print()
 
s = s.convert_dtypes()
print(s.dtypes)
print(s)
print()

Opět vidíme, že se konverze provedla na typ Int64:

object
0    100
1    200
2    300
3    400
4    500
5    600
dtype: object
 
Int64
0    100
1    200
2    300
3    400
4    500
5    600
dtype: Int64

Mimochodem – podporován je i typ float16, který je v některých případech užitečný:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100, 200, 300, 400, 500, 600))
print(s.dtypes)
print(s)
print()
 
s = s.astype('float16')
print(s.dtypes)
print(s)
print()

S výsledkem:

int64
0    100
1    200
2    300
3    400
4    500
5    600
dtype: int64
 
float16
0    100.0
1    200.0
2    300.0
3    400.0
4    500.0
5    600.0
dtype: float16

10. Použití hodnot None, resp. numpy.nan

Při konverzi je nutné počítat s tím, že vstupní data mohou obsahovat hodnoty None, resp. numpy.nan. Vyzkoušejme si tedy, jak na tyto hodnoty zareaguje konverzní funkce convert_dtypes popsaná v předchozí kapitole:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100, 200, 300, None, 400, 500, 600))
print(s.dtypes)
print(s)
print()
 
s = s.convert_dtypes()
print(s.dtypes)
print(s)
print()

Výsledkem je převod na Int64 (s velkým „I“ na začátku):

float64
0    100.0
1    200.0
2    300.0
3      NaN
4    400.0
5    500.0
6    600.0
dtype: float64
 
Int64
0     100
1     200
2     300
3    <NA>
4     400
5     500
6     600
dtype: Int64

Povodně v případě, že jedna z hodnot je typu float64:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
s = pandas.Series((100.1, 200, 300, None, 400, 500, 600))
print(s.dtypes)
print(s)
print()
 
s = s.convert_dtypes()
print(s.dtypes)
print(s)
print()

S výsledkem (bez převodu na jiný typ):

float64
0    100.1
1    200.0
2    300.0
3      NaN
4    400.0
5    500.0
6    600.0
dtype: float64
 
float64
0    100.1
1    200.0
2    300.0
3      NaN
4    400.0
5    500.0
6    600.0
dtype: float64

Na vstupu taktéž mnohdy nalezneme hodnotu numpy.nan a nikoli Null:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
import numpy
 
s = pandas.Series((100, 200, 300, numpy.nan, 400, 500, 600))
print(s.dtypes)
print(s)
print()
 
s = s.convert_dtypes()
print(s.dtypes)
print(s)
print()

Taková datová řada se převede na typ Int64 a numpy.nan se převede na NA:

float64
0    100.0
1    200.0
2    300.0
3      NaN
4    400.0
5    500.0
6    600.0
dtype: float64
 
Int64
0     100
1     200
2     300
3    <NA>
4     400
5     500
6     600
dtype: Int64

11. Vykreslení hodnot prvků z datové řady formou grafu

Již v předchozím článku jsme se zabývali popisem vykreslení grafů z hodnot uložených v datovém rámci. Grafy je ovšem možné vytvářet i z běžné datové řady, a to podobným způsobem – primárně s využitím knihovny Matplotlib. U každé datové řady jsou k dispozici následující metody sloužící k vykreslení grafů:

# Metoda Stručný popis
1 pandas.Series.plot graf vybraný parametrem kind
2 pandas.Series.plot.area oblast pod průběhem je vyplněna barvou (pro kladné hodnoty)
3 pandas.Series.plot.bar sloupcový graf s vertikálně orientovanými sloupci
4 pandas.Series.plot.barh sloupcový graf s horizontálně orientovanými sloupci
5 pandas.Series.plot.box krabicový diagram
6 pandas.Series.plot.density diagram založený na KDE
7 pandas.Series.plot.hist histogram (bude použit příště)
8 pandas.Series.plot.kde diagram založený na KDE
9 pandas.Series.plot.line stejné jako pandas.Series.plot
10 pandas.Series.plot.pie koláčový diagram
11 pandas.Series.hist histogram (bude použit příště)

V navazujících kapitolách si některé z těchto grafů ukážeme.

Poznámka: jedním z důvodů, proč je vykreslení grafu z datové řady užitečné, je korektní práce s hodnotami NA a taktéž unifikovaný přístup k celé problematice v rámci celé knihovny Pandas.

12. Liniový (spojnicový) graf a graf s vyplněnou plochou pod liniovým grafem

Prvním typem grafu, s nímž se v dnešním článku seznámíme, je takzvaný spojnicový či liniový graf. Ten se poměrně často využívá například ve finančnictví (kde bývá různě upravován do svíčkového grafu atd). Vytvoření takového grafu z datové řady je většinou triviální, což je ostatně ukázáno i v dalším demonstračním příkladu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot()
 
# uložení grafu
plt.savefig("series_plot_01.png")
 
# vykreslení grafu
plt.show()
Poznámka: proměnná r slouží jak ke specifikaci indexů, tak i vstupních hodnot pro výpočet sinusovky.

Výsledný graf by měl vypadat následovně:

Obrázek 1: Jednoduchý liniový graf.

Vytvořit je možné i graf s vyplněnou plochou pod liniovým grafem (nebo nad liniovým grafem pro záporné hodnoty). V tomto případě je možné využít (resp. spíše zneužít) metodu pandas.Series.plot.area tak, jak je ukázáno v dalším demonstračním příkladu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot.area(stacked=False)
 
# uložení grafu
plt.savefig("series_plot_02.png")
 
# vykreslení grafu
plt.show()
Poznámka: parametr stacked by měl být v tomto případě explicitně nastaven na False.

Obrázek 2: Graf s vyplněnou plochou pod liniovým grafem.

13. Vertikální i horizontální sloupcové grafy

Jedním z nejjednodušších typů grafů podporovaných Pandasem je sloupcový graf, který může být podle konkrétních požadavků orientován jak horizontálně tak i vertikálně. Tento typ grafu se vytváří zavoláním metody pandas.Series.plot.bar, popř. pandas.Series.plot.barh. Podívejme se nyní na jednoduchý příklad vertikálního sloupcového grafu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 20)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot.bar(grid=True)
 
# uložení grafu
plt.savefig("series_plot_03.png")
 
# vykreslení grafu
plt.show()

Obrázek 3: Vertikální sloupcový graf.

Horizontální sloupcový graf, v němž jsou sloupce vodorovné, se ze vstupních dat vykreslí takto:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 20)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot.barh(grid=True)
 
# uložení grafu
plt.savefig("series_plot_04.png")
 
# vykreslení grafu
plt.show()

Obrázek 4: Horizontální sloupcový graf.

14. Graf s KDE (Kernel density estimation)

V knihovně Pandas nalezneme i metodu nazvanou pandas.Series.plot.kde, která slouží pro vykreslení zobecněného histogramu s využitím KDE neboli Kernel density estimation. Narozdíl od histogramu umožňuje KDE lépe popsat skutečné chování dat, kterých se předpokládá, že tvoří spojitou funkci:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot.kde(grid=True)
 
# uložení grafu
plt.savefig("series_plot_05.png")
 
# vykreslení grafu
plt.show()

Obrázek 5: Graf s KDE (Kernel density estimation).

15. Koláčový diagram

Dalším typem grafu, s nímž se v dnešním článku seznámíme, jsou takzvané koláčové grafy, které již každý čtenář zcela jistě viděl. Tyto typy grafů se používají v případě, že nás nezajímají absolutní hodnoty, ale hodnoty relativní, konkrétně vzájemné poměry. I tyto grafy je možné v případě datových řad využít a jejich výhodou je, že v implicitním nastavení jsou vykresleny ve 2D tvaru (protože trojrozměrné koláčové diagramy jsou z hlediska přehlednosti i poměrů vykreslených hodnot prakticky to vůbec nejhorší možné řešení – možná právě proto se s nimi tak často setkáme, pravděpodobně nejvíce ve chvíli, kdy nás mají tyto diagramy za úkol zmást).

Budeme vykreslovat datovou řadu získanou z tohoto souboru:

Sep 2020  Sep 2019  Change    Language           Ratings   Changep
1         2         change    C                  15.95     +0.74
2         1         change    Java               13.48     -3.18
3         3                   Python             10.47     +0.59
4         4                   C++                7.11      +1.48
5         5                   C#                 4.58      +1.18
6         6                   Visual Basic       4.12      +0.83
7         7                   JavaScript         2.54      +0.41
8         9         change    PHP                2.49      +0.62
9         19        change    R                  2.37      +1.33
10        8         change    SQL                1.76      -0.19
11        14        change    Go                 1.46      +0.24
12        16        change    Swift              1.38      +0.28
13        20        change    Perl               1.30      +0.26
14        12        change    Assembly language  1.30      -0.08
15        15                  Ruby               1.24      +0.03
16        18        change    MATLAB             1.10      +0.04
17        11        change    Groovy             0.99      -0.52
18        33        change    Rust               0.92      +0.55
19        10        change    Objective-C        0.85      -0.99
20        24        change    Dart               0.77      +0.13

Z tohoto souboru získáme sloupec Ratings s hodnotami datové řady a sloupec Language bude sloužit namísto indexů:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# přečtení zdrojových dat
df = pandas.read_csv("tiobe.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df.set_index("Language", inplace=True)
 
# pro jistotu si datový rámec zobrazíme
print(df)
 
# konstrukce struktury Series - datové řady z datového rámce
s = pandas.Series(df["Ratings"])
 
# tisk obsahu Series
print(s)
 
# vytvoření grafu
s.plot.pie()
 
# uložení grafu
plt.savefig("series_plot_06.png")
 
# vykreslení grafu
plt.show()

Obrázek 6: Koláčový graf vykreslený předchozím demonstračním příkladem.

16. Data obsahující šum

Data ukládaná do datových řad nebo datových rámců obsahují mnohdy i určitý šum. Ten si můžeme – prozatím velmi primitivním způsobem – nasimulovat například pomocí metody pandas.Series.map, která ovlivní každý prvek datové řady:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# přidání šumu
s2 = s.map(lambda x: x+np.random.rand()/2)
 
# tisk obsahu Series
print(s2)
 
# vytvoření grafu
s2.plot(grid=True)
 
# uložení grafu
plt.savefig("series_plot_07.png")
 
# vykreslení grafu
plt.show()

Tento příklad sice ukazuje použití map, ovšem rychlejší bude „vektorový“ přístup. Zde se ukazuje možnost vektorového součtu datové řady a pole v Numpy:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce datové struktury Series
s = pandas.Series(data=np.sin(r), index=r)
 
# šum
s2 = np.random.rand(100)/2
 
# přidání šumu k původní řadě
s3 = s + s2
 
# tisk obsahu Series
print(s3)
 
# vytvoření grafu
s3.plot(grid=True)
 
# uložení grafu
plt.savefig("series_plot_07_B.png")
 
# vykreslení grafu
plt.show()

Po spuštění tohoto příkladu by se měl zobrazit následující graf:

Obrázek 7: Zašuměná data.

17. Vyhlazení průběhu na grafu

V této kapitole si ve stručnosti popíšeme, jak lze vyhladit průběh zobrazený na grafu. Nejdříve si připravíme novou datovou řadu, která sice vychází z původní sinusovky, ale přidává do ní šum. Následně s využitím posuvného okna (rolling) průběh vyhladíme, přičemž se pro vyhlazení (jednoduchý moving average) použije okno široké dva vzorky:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# přidání šumu
s2 = s.map(lambda x: x+np.random.rand()/2)
 
# vyhlazení (moving average)
s3 = s2.rolling(2).mean()
 
# tisk obsahu Series
print(s3)
 
# vytvoření grafu
s3.plot(grid=True)
 
# uložení grafu
plt.savefig("series_plot_08.png")
 
# vykreslení grafu
plt.show()

Obrázek 8: Částečné vyhlazení původně zašuměných dat.

Oblast, ze které se berou vzorky pro vyhlazení, ovšem může být i širší, například dvacet vzorků:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
# přidání šumu
s2 = s.map(lambda x: x+np.random.rand()/2)
 
# vyhlazení (moving average)
s3 = s2.rolling(20).mean()
 
# tisk obsahu Series
print(s3)
 
# vytvoření grafu
s3.plot(grid=True)
 
# uložení grafu
plt.savefig("series_plot_09.png")
 
# vykreslení grafu
plt.show()

Obrázek 9: Vyhlazení zašuměných dat s využitím širší oblasti.

A konečně je možné využít i další metody vyhlazení, například s váhováním vzorků založeným na slavné Gaussově funkci:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
s2 = s.map(lambda x: x+np.random.rand()/2)
 
s3 = s2.rolling(10, win_type="gaussian").sum(std=3)
 
# tisk obsahu Series
print(s3)
 
# vytvoření grafu
s3.plot(grid=True)
 
# uložení grafu
plt.savefig("series_plot_10.png")
 
# vykreslení grafu
plt.show()

Výsledek bude vypadat následovně:

Obrázek 10: Použití Gaussovy funkce pro výpočet vah vzorků při vyhlazování.

18. Graf s několika průběhy získanými z datové řady, použití podgrafů

Často se setkáme s požadavkem zobrazit do jednoho grafu průběhy získané z několika datových řad. V takových případech už není možné použít nějakou metodu pandas.Series.plot.xxx, ale budeme muset zkombinovat možnosti knihoven PandasMatplotlib. To je ukázáno v následujícím demonstračním příkladu, v němž jsou nejdříve vytvořeny tři datové řady s, s2 a s3 a následně jsou všechny tyto řady vykresleny funkcí matplotlib.pyplot.plot (ony řetězce „–“ a „-“ popisují styl vykreslení):

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
s2 = s.map(lambda x: x+np.random.rand()/2)
 
s3 = s2 - s
 
# vytvoření grafu
plt.plot(s, "--", s2, "-", s3, "-")
 
# uložení grafu
plt.savefig("series_plot_11.png")
 
# vykreslení grafu
plt.show()

S výsledkem:

Obrázek 11: Graf se třemi průběhy; hodnoty byly získány ze tří datových řad.

Druhý požadavek vychází z potřeby zobrazit na jednu plochu více grafů. V tomto případě se někdy mluví o podgrafech, což však v daném kontextu nemá matematický význam. V dnešním posledním demonstračním příkladu je ukázáno, jak se na ploše pro zobrazení grafu vytvoří místo pro čtyři podgrafy, které se následně využije. Hodnota „221“ znamená „mřížka o rozměrech 2×2 buňky, první buňka v této mřížce“:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import numpy as np
import pandas
import matplotlib.pyplot as plt
 
# hodnoty na x-ové ose
r = np.linspace(0, 2*np.pi, 100)
 
# konstrukce struktury Series - datové řady
s = pandas.Series(data=np.sin(r), index=r)
 
s2 = s.map(lambda x: x+np.random.rand()/2)
 
s3 = s2 - s
 
# vytvoření grafu
plt.subplot(221)
plt.plot(s)
 
plt.subplot(222)
plt.plot(s2)
 
plt.subplot(223)
plt.plot(s3)
 
# uložení grafu
plt.savefig("series_plot_12.png")
 
# vykreslení grafu
plt.show()

S výsledkem:

Obrázek 12: Tři grafy (podgrafy) vykreslené na jedinou společnou plochu.

DT2021 tip

19. Repositář s demonstračními příklady

Zdrojové kódy všech dnes popsaných demonstračních příkladů určených pro Python 3 a nejnovější stabilní verzi knihovny Pandas byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs. V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má velikost zhruba několik desítek kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:

# Demonstrační příklad Stručný popis příkladu Cesta
1 data_frame_info1.py výpis obsahu datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info1.py
2 data_frame_info2.py výpis prvních pěti řádků z datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info2.py
3 data_frame_info3.py výpis informace o typech sloupců v datovém rámci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info3.py
4 data_frame_info4.py výpis uspořádaného seznamu jmen všech sloupců https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info4.py
5 data_frame_info5.py podrobnější informace o datovém rámci, obsazení paměti atd. https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info5.py
6 data_frame_info6.py podrobnější informace o datovém rámci, obsazení paměti atd. https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info6.py
7 data_frame_info7.py popis os, počtu dimenzí, tvaru a velikosti datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info7.py
8 data_frame_info8.py základní statistické informace o datech uložených v rámci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info8.py
9 data_frame_info9.py výsledkem metody info je nový datový rámec https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_info9.py
       
10 plot_kafka_lags.py zobrazení jednoduchého grafu bez použití knihovny Pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags.py
11 plot_kafka_lags_pandas.py zobrazení jednoduchého grafu s použitím knihovny Pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags_pandas.py
12 plot_kafka_lags_pandas2.py snazší způsob vykreslení grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags_pandas2.py
13 plot_kafka_lags_pandas_sma3.py přidání klouzavého průměru do grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags_pandas_sma3.py
14 plot_kafka_lags_pandas_sma3_.py vylepšení předchozího příkladu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags_pandas_sma3_.py
15 plot_kafka_lags_pandas_sma10.py klouzavý průměr přes deset hodnot https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_kaf­ka_lags_pandas_sma10.py
16 plot_benchmark_results_line_chart.py liniový graf https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_ben­chmark_results_line_chart­.py
17 plot_benchmark_results_bar_chart1.py sloupcový graf https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_ben­chmark_results_bar_chart.py
18 plot_benchmark_results_bar_chart2.py výběr části datového rámce při vykreslování grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_ben­chmark_results_bar_chart.py
19 plot_benchmark_results_bar_chart3.py zobecnění předchozího příkladu – zpracování numerických dat ve všech sloupcích https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_ben­chmark_results_bar_chart.py
       
20 check_types1.py kontrola typů sloupců s využitím knihovny Voluptuous https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/chec­k_types1.py
21 check_types2.py kontrola typů sloupců s využitím knihovny Voluptuous https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/chec­k_types2.py
22 check_types3.py kontrola typů sloupců s využitím knihovny Voluptuous https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/chec­k_types3.py
23 check_types4.py kontrola typů sloupců s využitím knihovny Voluptuous https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/chec­k_types4.py
24 check_types5.py kontrola typů sloupců s využitím knihovny Voluptuous https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/chec­k_types5.py
25 opulent_pandas1.py kontrola typů sloupců s využitím knihovny opulent-pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/o­pulent_pandas1.py
26 opulent_pandas2.py kontrola typů sloupců s využitím knihovny opulent-pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/o­pulent_pandas2.py
27 opulent_pandas3.py kontrola typů sloupců s využitím knihovny opulent-pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/o­pulent_pandas3.py
28 opulent_pandas4.py kontrola typů sloupců s využitím knihovny opulent-pandas https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/o­pulent_pandas4.py
       
29 series01.py konstrukce datové řady z n-tice https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series01.py
30 series02.py konstrukce datové řady z n-tice, specifikace indexů https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series02.py
31 series03.py konstrukce datové řady generátorem, specifikace indexů https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series03.py
32 series04.py příliš malý počet indexů předaných konstruktoru https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series04.py
33 series05.py konstrukce datové řady ze slovníku https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series05.py
34 series06.py konstrukce datové řady ze slovníku, vliv pořadí klíčů https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series06.py
35 series07.py konstrukce datové řady z datového typu OrderedDict https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series07.py
36 series08.py vytvoření nové datové řady z řady stávající – výběr prvků na základě jejich indexů https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series08.py
37 series09.py základní statistické informace o prvcích uložených v datové řadě https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series09.py
38 series10.py vektorové operace nad všemi prvky datové řady https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series10.py
39 series11.py vektorové operace nad všemi prvky datové řady – predikáty https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series11.py
40 series12.py vektorové operace nad dvojicí datových řad https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series12.py
41 series13.py výběr prvků na základě podmínky https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series13.py
42 series14.py výběr prvků na základě podmínky https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series14.py
43 series15.py převody mezi různými datovými typy https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series15.py
44 series16.py převody mezi různými datovými typy https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series16.py
45 series17.py převody mezi různými datovými typy https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series17.py
46 series18.py převody mezi různými datovými typy – s hodnotami None https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series18.py
47 series19.py převody mezi různými datovými typy – s hodnotami None https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series19.py
48 series20.py převody mezi různými datovými typy – s hodnotami NaN https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/series20.py
       
49 plot_series01.py vykreslení průběhu funkce sin, hodnoty jsou uloženy v datové řadě https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries01.py
50 plot_series02.py odlišný typ grafu s vyplněnou plochou pod průběhem funkce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries02.py
51 plot_series03.py sloupcový diagram s vertikálně orientovanými sloupci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries03.py
52 plot_series04.py sloupcový diagram s horizontálně orientovanými sloupci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries04.py
53 plot_series05.py graf s KDE – kernel density estimation https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries05.py
54 plot_series06.py vykreslení koláčového grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries06.py
55 plot_series07.py použití metody Series.map https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries07.py
56 plot_series08.py vyhlazení grafu s průběhem zašuměného signálu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries08.py
57 plot_series09.py vyhlazení grafu s průběhem zašuměného signálu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries09.py
58 plot_series10.py Gaussovské vyhlazení grafu s průběhem zašuměného signálu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries10.py
59 plot_series11.py vykreslení tří průběhů do jediného grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries11.py
60 plot_series12.py vykreslení tří podgrafů do jednoho grafu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/plot_se­ries12.py

Některé demonstrační příklady načítají následující soubory s daty:

# Datový soubor Stručný popis souboru Cesta
1 integer_values.csv dvousloupcová tabulka s celými čísly https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/in­teger_values.csv
2 missing_integer_values.csv dvousloupcová tabulka s celými čísly, z nichž některé chybí https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/mis­sing_integer_values.csv
3 timestamps.csv tabulka s časovými údaji https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/timestamps.csv
4 custom_timestamps.csv tabulka s časovými údaji používajícími nestandardní formát https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/cus­tom_timestamps.csv
5 denni_kurz.txt semistrukturovaný soubor s nestandardními oddělovači https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/denni_kurz.txt
6 tiobe.tsv data získaná ze stránek Tiobe indexu ve formátu TSV https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobe.tsv
7 tiobe.txt data získaná ze stránek Tiobe indexu v textovém formátu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobe.txt
8 benchmarks1.tsv výsledky benchmarků několika implementací Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/ben­chmarks1.tsv
9 benchmarks2.tsv výsledky benchmarků několika implementací Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/ben­chmarks2.tsv

20. Odkazy na Internetu

  1. Plotting with matplotlib
    https://pandas.pydata.org/pandas-docs/version/0.13/visualization.html
  2. Plot With Pandas: Python Data Visualization for Beginners
    https://realpython.com/pandas-plot-python/
  3. Pandas Dataframe: Plot Examples with Matplotlib and Pyplot
    https://queirozf.com/entries/pandas-dataframe-plot-examples-with-matplotlib-pyplot
  4. Opulent-Pandas na PyPi
    https://pypi.org/project/opulent-pandas/
  5. pandas_validator na PyPi
    https://pypi.org/project/pan­das_validator/
  6. pandas-validator (dokumentace)
    https://pandas-validator.readthedocs.io/en/latest/
  7. 7 Best Python Libraries for Validating Data
    https://www.yeahhub.com/7-best-python-libraries-validating-data/
  8. Universally unique identifier (Wikipedia)
    https://en.wikipedia.org/wi­ki/Universally_unique_iden­tifier
  9. Nullable integer data type
    https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html
  10. pandas.read_csv
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pan­das.read_csv.html
  11. How to define format when using pandas to_datetime?
    https://stackoverflow.com/qu­estions/36848514/how-to-define-format-when-using-pandas-to-datetime
  12. Pandas : skip rows while reading csv file to a Dataframe using read_csv() in Python
    https://thispointer.com/pandas-skip-rows-while-reading-csv-file-to-a-dataframe-using-read_csv-in-python/
  13. Skip rows during csv import pandas
    https://stackoverflow.com/qu­estions/20637439/skip-rows-during-csv-import-pandas
  14. Denni kurz
    https://www.cnb.cz/cs/finan­cni_trhy/devizovy_trh/kur­zy_devizoveho_trhu/denni_kur­z.txt
  15. UUID objects according to RFC 4122 (knihovna pro Python)
    https://docs.python.org/3­.5/library/uuid.html#uuid­.uuid4
  16. Object identifier (Wikipedia)
    https://en.wikipedia.org/wi­ki/Object_identifier
  17. Digital object identifier (Wikipedia)
    https://en.wikipedia.org/wi­ki/Digital_object_identifi­er
  18. voluptuous na (na PyPi)
    https://pypi.python.org/py­pi/voluptuous
  19. Repositář knihovny voluptuous na GitHubu
    https://github.com/alectho­mas/voluptuous
  20. pytest-voluptuous 1.0.2 (na PyPi)
    https://pypi.org/project/pytest-voluptuous/
  21. pytest-voluptuous (na GitHubu)
    https://github.com/F-Secure/pytest-voluptuous
  22. schemagic 0.9.1 (na PyPi)
    https://pypi.python.org/py­pi/schemagic/0.9.1
  23. Schemagic / Schemagic.web (na GitHubu)
    https://github.com/Mechrop­hile/schemagic
  24. schema 0.6.7 (na PyPi)
    https://pypi.python.org/pypi/schema
  25. schema (na GitHubu)
    https://github.com/keleshev/schema
  26. XML Schema validator and data conversion library for Python
    https://github.com/brunato/xmlschema
  27. xmlschema 0.9.7
    https://pypi.python.org/py­pi/xmlschema/0.9.7
  28. jsonschema 2.6.0
    https://pypi.python.org/py­pi/jsonschema
  29. warlock 1.3.0
    https://pypi.python.org/pypi/warlock
  30. Python Virtual Environments – A Primer
    https://realpython.com/python-virtual-environments-a-primer/
  31. pip 1.1 documentation: Requirements files
    https://pip.readthedocs.i­o/en/1.1/requirements.html
  32. unittest.mock — mock object library
    https://docs.python.org/3­.5/library/unittest.mock.html
  33. mock 2.0.0
    https://pypi.python.org/pypi/mock
  34. An Introduction to Mocking in Python
    https://www.toptal.com/python/an-introduction-to-mocking-in-python
  35. Unit testing (Wikipedia)
    https://en.wikipedia.org/wi­ki/Unit_testing
  36. Unit testing
    https://cs.wikipedia.org/wi­ki/Unit_testing
  37. Test-driven development (Wikipedia)
    https://en.wikipedia.org/wiki/Test-driven_development
  38. Pip (dokumentace)
    https://pip.pypa.io/en/stable/
  39. 5 Differences between clojure.spec and Schema
    https://lispcast.com/clojure.spec-vs-schema/
  40. Schema: Clojure(Script) library for declarative data description and validation
    https://github.com/plumatic/schema
  41. clojure.spec – Rationale and Overview
    https://clojure.org/about/spec