Hlavní navigace

Knihovna Pandas: spojování datových rámců s využitím append, concat, merge a join

31. 12. 2020
Doba čtení: 50 minut

Sdílet

Před vlastní analýzou či statistickým zpracováním dat s využitím knihovny Pandas je mnohdy nutné data získat z několika samostatných tabulek, jež je zapotřebí načíst a spojit.

Obsah

1. Načtení datového rámce z externího datového souboru (tabulky)

2. Zpracování jednotlivých sloupců v datových rámcích – map a transform

3. Agregace dat z datových rámců, resp. z vybraných sloupců

4. Použití metody combine

5. Spojení datových rámců metodou append

6. Příklad použití metody append

7. Spojení rámců po sloupcích nebo po řádcích funkcí concat

8. Příklady použití funkce concat

9. Funkce merge

10. Inner join (vnitřní spojení) založený na funkci merge

11. Left join (vnější spojení „zleva“) založený na funkci merge

12. Right join (vnější spojení „zprava“) založený na funkci merge

13. Outer join (vnější spojení) založený na funkci merge

14. Použití metody join pro spojení dvou datových rámců

15. Inner join (vnitřní spojení) založený na metodě join

16. Left join (vnější spojení „zleva“) založený na metodě join

17. Right join (vnější spojení „zprava“) založený na metodě join

18. Outer join (vnější spojení) založený na metodě join

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

20. Odkazy na Internetu

1. Načtení datového rámce z externího datového souboru (tabulky)

Nejdříve si zopakujme, jakým způsobem je možné načíst tabulku do datového rámce. Knihovna Pandas umožňuje načtení tabulky z různých datových zdrojů, například ze:

  1. Souborů CSV (Comma-Separated Values)
  2. Souborů TSV (Tab-Separated Values)
  3. Textových souborů s volitelným oddělovačem a formátem sloupců
  4. Tabulek z tabulkových procesorů (xls, xlsx, xlsm, xlsb, odf, ods, odt)
  5. Souborů JSON se strukturovanými daty
  6. Načítání z relačních databází s využitím SQL driverů
  7. Načítání z Parquet souborů
  8. atd.

V demonstračních příkladech popsaných v navazujících kapitolách budeme používat tabulku uloženou ve formátu TSV (Tab-Separated Values), kterou je možné načíst funkcí nazvanou read_csv, ovšem jen v případě, že budeme explicitně specifikovat formát oddělovače:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()
Poznámka: povšimněte si, že vybraný sloupec je zkonvertován na index, čehož posléze využijeme.

Po spuštění tohoto demonstračního příkladu by se měl nejprve zobrazit obsah celého datového rámce:

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

Následovat by měl výpis struktury jednotlivých sloupců:

Sep 2020      int64
Sep 2019      int64
Change       object
Ratings     float64
Changep     float64
dtype: object

Nakonec se zobrazí informace o indexech, popis všech pěti datových sloupců a obsazení paměti datovým rámcem:

<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     float64
 4   Changep   20 non-null     float64
dtypes: float64(2), int64(2), object(1)
memory usage: 960.0+ bytes
None

2. Zpracování jednotlivých sloupců v datových rámcích – map a transform

V předchozím článku o knihovně Pandas jsme si popsali mnoho funkcí určených pro zpracování datových řad (series). Všechny tyto funkce jsou přitom plně aplikovatelné i na sloupce datových rámců, protože každý sloupec je možné považovat za plnohodnotnou datovou řadu. Vzhledem k tomu, že jednotlivé funkce již byly poměrně podrobně popsány minule, ukážeme si dnes jen několik příkladů pouze se základním popisem.

Vytvoření nového sloupce založeného na hodnotách z existujícího sloupce „Ratings“:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# převod na skutečný poměr <0, 1>
df["Ratings as ratio"] = df["Ratings"].map(lambda x: x/100.0)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledkem bude následující datový rámec:

                   Sep 2020  Sep 2019  ... Changep  Ratings as ratio
Language
C                         1         2  ...    0.74            0.1595
Java                      2         1  ...   -3.18            0.1348
Python                    3         3  ...    0.59            0.1047
C++                       4         4  ...    1.48            0.0711
C#                        5         5  ...    1.18            0.0458
Visual Basic              6         6  ...    0.83            0.0412
JavaScript                7         7  ...    0.41            0.0254
PHP                       8         9  ...    0.62            0.0249
R                         9        19  ...    1.33            0.0237
SQL                      10         8  ...   -0.19            0.0176
Go                       11        14  ...    0.24            0.0146
Swift                    12        16  ...    0.28            0.0138
Perl                     13        20  ...    0.26            0.0130
Assembly language        14        12  ...   -0.08            0.0130
Ruby                     15        15  ...    0.03            0.0124
MATLAB                   16        18  ...    0.04            0.0110
Groovy                   17        11  ...   -0.52            0.0099
Rust                     18        33  ...    0.55            0.0092
Objective-C              19        10  ...   -0.99            0.0085
Dart                     20        24  ...    0.13            0.0077
 
[20 rows x 6 columns]
 
Sep 2020              int64
Sep 2019              int64
Change               object
Ratings             float64
Changep             float64
Ratings as ratio    float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 6 columns):
 #   Column            Non-Null Count  Dtype
---  ------            --------------  -----
 0   Sep 2020          20 non-null     int64
 1   Sep 2019          20 non-null     int64
 2   Change            14 non-null     object
 3   Ratings           20 non-null     float64
 4   Changep           20 non-null     float64
 5   Ratings as ratio  20 non-null     float64
dtypes: float64(3), int64(2), object(1)
memory usage: 1.1+ KB
None

Přepis původního sloupce „Ratings“ zkonvertovanými hodnotami:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# převod na skutečný poměr <0, 1>
df["Ratings"] = df["Ratings"].map(lambda x: x/100.0)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledkem tohoto příkladu bude následující datový rámec:

                   Sep 2020  Sep 2019  Change  Ratings  Changep
Language
C                         1         2  change   0.1595     0.74
Java                      2         1  change   0.1348    -3.18
Python                    3         3     NaN   0.1047     0.59
C++                       4         4     NaN   0.0711     1.48
C#                        5         5     NaN   0.0458     1.18
Visual Basic              6         6     NaN   0.0412     0.83
JavaScript                7         7     NaN   0.0254     0.41
PHP                       8         9  change   0.0249     0.62
R                         9        19  change   0.0237     1.33
SQL                      10         8  change   0.0176    -0.19
Go                       11        14  change   0.0146     0.24
Swift                    12        16  change   0.0138     0.28
Perl                     13        20  change   0.0130     0.26
Assembly language        14        12  change   0.0130    -0.08
Ruby                     15        15     NaN   0.0124     0.03
MATLAB                   16        18  change   0.0110     0.04
Groovy                   17        11  change   0.0099    -0.52
Rust                     18        33  change   0.0092     0.55
Objective-C              19        10  change   0.0085    -0.99
Dart                     20        24  change   0.0077     0.13
 
Sep 2020      int64
Sep 2019      int64
Change       object
Ratings     float64
Changep     float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     float64
 4   Changep   20 non-null     float64
dtypes: float64(2), int64(2), object(1)
memory usage: 960.0+ bytes
None

Přímá aplikace funkce format bez nutnosti použití lambda výrazu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# formát hodnot ve sloupci
df["Ratings"] = df["Ratings"].map("Rating is {:4.1f}%".format)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledek:

                   Sep 2020  Sep 2019  Change          Ratings  Changep
Language
C                         1         2  change  Rating is 15.9%     0.74
Java                      2         1  change  Rating is 13.5%    -3.18
Python                    3         3     NaN  Rating is 10.5%     0.59
C++                       4         4     NaN  Rating is  7.1%     1.48
C#                        5         5     NaN  Rating is  4.6%     1.18
Visual Basic              6         6     NaN  Rating is  4.1%     0.83
JavaScript                7         7     NaN  Rating is  2.5%     0.41
PHP                       8         9  change  Rating is  2.5%     0.62
R                         9        19  change  Rating is  2.4%     1.33
SQL                      10         8  change  Rating is  1.8%    -0.19
Go                       11        14  change  Rating is  1.5%     0.24
Swift                    12        16  change  Rating is  1.4%     0.28
Perl                     13        20  change  Rating is  1.3%     0.26
Assembly language        14        12  change  Rating is  1.3%    -0.08
Ruby                     15        15     NaN  Rating is  1.2%     0.03
MATLAB                   16        18  change  Rating is  1.1%     0.04
Groovy                   17        11  change  Rating is  1.0%    -0.52
Rust                     18        33  change  Rating is  0.9%     0.55
Objective-C              19        10  change  Rating is  0.8%    -0.99
Dart                     20        24  change  Rating is  0.8%     0.13
 
Sep 2020      int64
Sep 2019      int64
Change       object
Ratings      object
Changep     float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     object
 4   Changep   20 non-null     float64
dtypes: float64(1), int64(2), object(2)
memory usage: 960.0+ bytes
None

Metoda transform odpovídá výše zmíněné metodě map:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# převod na skutečný poměr <0, 1>
df["Ratings as ratio"] = df["Ratings"].transform(lambda x: x/100.0)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledek:

                   Sep 2020  Sep 2019  ... Changep  Ratings as ratio
Language
C                         1         2  ...    0.74            0.1595
Java                      2         1  ...   -3.18            0.1348
Python                    3         3  ...    0.59            0.1047
C++                       4         4  ...    1.48            0.0711
C#                        5         5  ...    1.18            0.0458
Visual Basic              6         6  ...    0.83            0.0412
JavaScript                7         7  ...    0.41            0.0254
PHP                       8         9  ...    0.62            0.0249
R                         9        19  ...    1.33            0.0237
SQL                      10         8  ...   -0.19            0.0176
Go                       11        14  ...    0.24            0.0146
Swift                    12        16  ...    0.28            0.0138
Perl                     13        20  ...    0.26            0.0130
Assembly language        14        12  ...   -0.08            0.0130
Ruby                     15        15  ...    0.03            0.0124
MATLAB                   16        18  ...    0.04            0.0110
Groovy                   17        11  ...   -0.52            0.0099
Rust                     18        33  ...    0.55            0.0092
Objective-C              19        10  ...   -0.99            0.0085
Dart                     20        24  ...    0.13            0.0077
 
[20 rows x 6 columns]
 
Sep 2020              int64
Sep 2019              int64
Change               object
Ratings             float64
Changep             float64
Ratings as ratio    float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 6 columns):
 #   Column            Non-Null Count  Dtype
---  ------            --------------  -----
 0   Sep 2020          20 non-null     int64
 1   Sep 2019          20 non-null     int64
 2   Change            14 non-null     object
 3   Ratings           20 non-null     float64
 4   Changep           20 non-null     float64
 5   Ratings as ratio  20 non-null     float64
dtypes: float64(3), int64(2), object(1)
memory usage: 1.7+ KB
None

Dtto pro změnu obsahu vybraného sloupce „Ratings“:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# převod na skutečný poměr <0, 1>
df["Ratings"] = df["Ratings"].transform(lambda x: x/100.0)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledek:

                   Sep 2020  Sep 2019  Change  Ratings  Changep
Language
C                         1         2  change   0.1595     0.74
Java                      2         1  change   0.1348    -3.18
Python                    3         3     NaN   0.1047     0.59
C++                       4         4     NaN   0.0711     1.48
C#                        5         5     NaN   0.0458     1.18
Visual Basic              6         6     NaN   0.0412     0.83
JavaScript                7         7     NaN   0.0254     0.41
PHP                       8         9  change   0.0249     0.62
R                         9        19  change   0.0237     1.33
SQL                      10         8  change   0.0176    -0.19
Go                       11        14  change   0.0146     0.24
Swift                    12        16  change   0.0138     0.28
Perl                     13        20  change   0.0130     0.26
Assembly language        14        12  change   0.0130    -0.08
Ruby                     15        15     NaN   0.0124     0.03
MATLAB                   16        18  change   0.0110     0.04
Groovy                   17        11  change   0.0099    -0.52
Rust                     18        33  change   0.0092     0.55
Objective-C              19        10  change   0.0085    -0.99
Dart                     20        24  change   0.0077     0.13
 
Sep 2020      int64
Sep 2019      int64
Change       object
Ratings     float64
Changep     float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     float64
 4   Changep   20 non-null     float64
dtypes: float64(2), int64(2), object(1)
memory usage: 1.6+ KB
None

Přímá specifikace metody format namísto lambda výrazu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# formát hodnot ve sloupci
df["Ratings"] = df["Ratings"].transform("Rating is {:4.1f}%".format)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

S výsledkem:

                   Sep 2020  Sep 2019  Change          Ratings  Changep
Language
C                         1         2  change  Rating is 15.9%     0.74
Java                      2         1  change  Rating is 13.5%    -3.18
Python                    3         3     NaN  Rating is 10.5%     0.59
C++                       4         4     NaN  Rating is  7.1%     1.48
C#                        5         5     NaN  Rating is  4.6%     1.18
Visual Basic              6         6     NaN  Rating is  4.1%     0.83
JavaScript                7         7     NaN  Rating is  2.5%     0.41
PHP                       8         9  change  Rating is  2.5%     0.62
R                         9        19  change  Rating is  2.4%     1.33
SQL                      10         8  change  Rating is  1.8%    -0.19
Go                       11        14  change  Rating is  1.5%     0.24
Swift                    12        16  change  Rating is  1.4%     0.28
Perl                     13        20  change  Rating is  1.3%     0.26
Assembly language        14        12  change  Rating is  1.3%    -0.08
Ruby                     15        15     NaN  Rating is  1.2%     0.03
MATLAB                   16        18  change  Rating is  1.1%     0.04
Groovy                   17        11  change  Rating is  1.0%    -0.52
Rust                     18        33  change  Rating is  0.9%     0.55
Objective-C              19        10  change  Rating is  0.8%    -0.99
Dart                     20        24  change  Rating is  0.8%     0.13
 
Sep 2020      int64
Sep 2019      int64
Change       object
Ratings      object
Changep     float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     object
 4   Changep   20 non-null     float64
dtypes: float64(1), int64(2), object(2)
memory usage: 1.6+ KB
None

3. Agregace dat z datových rámců, resp. z vybraných sloupců

S využitím agregačních funkcí je možné například získat maximální, minimální a průměrnou hodnotu ve vybraném sloupci, vypočítat součet nebo produkt hodnot ve sloupci atd. Zavolat lze funkce pro zpracování prvků polí poskytované knihovnou Numpy tak, jak je to ukázáno v dalším příkladu:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
import numpy as np
 
# 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)
 
# agregace výsledků
results = df["Ratings"].agg([np.min, np.max, np.sum, np.mean])
 
# tisk vypočtených výsledků
print("Results")
print(results)

Získané výsledky mají tvar datové řady:

Results
amin     0.770
amax    15.950
sum     76.180
mean     3.809
Name: Ratings, dtype: float64

Podobně koncipovaný příklad, ovšem nyní se použijí jména funkcí (uložené v řetězci) a nikoli reference na funkce:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# agregace výsledků
results = df["Ratings"].agg(["min", "max", "sum", "mean"])
 
# tisk vypočtených výsledků
print("Results")
print(results)

Vypočtené výsledky mají opět tvar datové řady:

Results
min      0.770
max     15.950
sum     76.180
mean     3.809
Name: Ratings, dtype: float64

4. Použití metody combine

Další užitečná metoda (popsaná minule), která je určená pro zpracování hodnot v datových řadách a tím pádem i ve sloupcích datových rámců, se jmenuje Series.combine. Tato metoda umožňuje zkombinovat prvky dvou řad (pokud jsou jejich indexy kompatibilní) popř. prvky jedné řady se skalární hodnotou. Ukažme si nyní druhý zmíněný případ, kdy zkombinujeme (postupně) hodnotu prvků z datové řady s hodnotou 2, resp. 10, přičemž kombinace bude provedena funkcemi min a max. V prvním případě tedy nahradíme ty prvky z řady, které jsou větší než 10 hodnotou 10 a následně ty prvky z řady, které jsou menší než 2 právě hodnotou 2:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# 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)
 
# omezení hodnot
df["Ratings"] = df["Ratings"].combine(10, min)
 
# omezení hodnot
df["Ratings"] = df["Ratings"].combine(2, max)
 
# datový rámec zobrazíme
print(df)
print()
 
# podrobnější informace o datovém rámci
print(df.dtypes)
print()
 
# více podrobnějších informací o datovém rámci
print(df.info())
print()

Výsledek je patrný při pohledu na nový obsah sloupce „Ratings“:

                   Sep 2020  Sep 2019  Change  Ratings  Changep
Language
C                         1         2  change    10.00     0.74
Java                      2         1  change    10.00    -3.18
Python                    3         3     NaN    10.00     0.59
C++                       4         4     NaN     7.11     1.48
C#                        5         5     NaN     4.58     1.18
Visual Basic              6         6     NaN     4.12     0.83
JavaScript                7         7     NaN     2.54     0.41
PHP                       8         9  change     2.49     0.62
R                         9        19  change     2.37     1.33
SQL                      10         8  change     2.00    -0.19
Go                       11        14  change     2.00     0.24
Swift                    12        16  change     2.00     0.28
Perl                     13        20  change     2.00     0.26
Assembly language        14        12  change     2.00    -0.08
Ruby                     15        15     NaN     2.00     0.03
MATLAB                   16        18  change     2.00     0.04
Groovy                   17        11  change     2.00    -0.52
Rust                     18        33  change     2.00     0.55
Objective-C              19        10  change     2.00    -0.99
Dart                     20        24  change     2.00     0.13
 
Sep 2020      int64
Sep 2019      int64
Change       object
Ratings     float64
Changep     float64
dtype: object
 
<class 'pandas.core.frame.DataFrame'>
Index: 20 entries, C to Dart
Data columns (total 5 columns):
 #   Column    Non-Null Count  Dtype
---  ------    --------------  -----
 0   Sep 2020  20 non-null     int64
 1   Sep 2019  20 non-null     int64
 2   Change    14 non-null     object
 3   Ratings   20 non-null     float64
 4   Changep   20 non-null     float64
dtypes: float64(2), int64(2), object(1)
memory usage: 960.0+ bytes
None

5. Spojení datových rámců metodou append

Ve druhé části dnešního článku se budeme zabývat velmi častou operací – spojením dvou (nebo i většího množství) datových rámců. V knihovně Pandas je možné rámce spojit jak „po řádcích“, tak i „po sloupcích“ a popř. i vyřešit splynutí hodnot z těch sloupců, které si logicky odpovídají. Nejdříve si ukážeme, jakým způsobem je možné spojit dva datové rámce „po řádcích“. K tomu využijeme datové soubory tiobeC.tsv a tiobeD.tsv.

První z těchto souborů tiobeC.tsv obsahuje horní polovinu tabulky:

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

Druhá polovina tabulky je uložena v souboru tiobeD.tsv:

Sep 2020    Sep 2019    Change      Language           Ratings     Changep
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

6. Příklad použití metody append

Metoda append třídy DataFrame připojí k datovému rámci obsah druhého datového rámce. Použití této metody v praxi je tedy velmi jednoduché, ovšem lze ji použít pouze pro základní operace s datovými rámci (na rozdíl od dále popsaných operací typu „merge“ a „join“):

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeC.tsv", sep="\t")
df2 = pandas.read_csv("tiobeD.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
concatenated = df1.append(df2)
 
# výpis výsledku
print(concatenated)

Po spuštění tohoto příkladu se nejdříve zobrazí původní obsah obou datových rámců:

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

Poté dojde k připojení druhého rámce k rámci prvnímu s tímto výsledkem:

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

7. Spojení rámců po sloupcích nebo po řádcích funkcí concat

Alternativní možnost spojení dvou datových rámců nabízí funkce nazvaná concat, která je aplikovatelná pro libovolný počet instancí třídy DataFrame. Tato funkce dokáže datové rámce spojit buď po sloupcích nebo po řádcích, a to v závislosti na hodnotě parametru axis, který by měl obsahovat hodnotu 0 nebo 1 (popř. nebýt vůbec uveden):

concat(objs:Union[Iterable[~FrameOrSeries], Mapping[collections.abc.Hashable, ~FrameOrSeries]], axis=0, join='outer', ignore_index:bool=False, keys=None, levels=None, names=None, verify_integrity:bool=False, sort:bool=False, copy:bool=True)
-> Union[_ForwardRef('DataFrame'), _ForwardRef('Series')]
 
    Concatenate pandas objects along a particular axis with optional set logic
    along the other axes.
 
    Can also add a layer of hierarchical indexing on the concatenation axis,
    which may be useful if the labels are the same (or overlapping) on
    the passed axis number.

Pro otestování spojení datových rámců „po řádcích“ opět použijeme datové soubory tiobeC.tsv a tiobeD.tsv popsané v rámci páté kapitoly. Ovšem pro spojení rámců „po sloupcích“ budou použity odlišné soubory – tiobeE.tsv a tiobeF.tsv.

Soubor tiobeE.tsv obsahuje pouze tři vybrané sloupce z původního rámce (tabulky):

Language           Ratings       Changep
C                  15.95         +0.74
Java               13.48         -3.18
Python             10.47         +0.59
C++                7.11          +1.48
C#                 4.58          +1.18
Visual Basic       4.12          +0.83
JavaScript         2.54          +0.41
PHP                2.49          +0.62
R                  2.37          +1.33
SQL                1.76          -0.19
Go                 1.46          +0.24
Swift              1.38          +0.28
Perl               1.30          +0.26
Assembly language  1.30          -0.08
Ruby               1.24          +0.03
MATLAB             1.10          +0.04
Groovy             0.99          -0.52
Rust               0.92          +0.55
Objective-C        0.85          -0.99
Dart               0.77          +0.13

Soubor tiobeF.tsv taktéž obsahuje pouze vybrané datové sloupce z původní tabulky:

Sep 2020         Sep 2019       Change         Language
1                2              change         C
2                1              change         Java
3                3                             Python
4                4                             C++
5                5                             C#
6                6                             Visual Basic
7                7                             JavaScript
8                9              change         PHP
9                19             change         R
10               8              change         SQL
11               14             change         Go
12               16             change         Swift
13               20             change         Perl
14               12             change         Assembly language
15               15                            Ruby
16               18             change         MATLAB
17               11             change         Groovy
18               33             change         Rust
19               10             change         Objective-C
20               24             change         Dart
Poznámka: povšimněte si, že sloupec „Language“ existuje v obou tabulkách. To je důležité, protože bude využit pro vytvoření indexů datových rámců.

8. Příklady použití funkce concat

Nejprve si ukažme, jak se provede spojení dvou datových rámců „po sloupcích“ s využitím funkce concat. V tomto případě je nutné funkci předat seznam nebo n-tici, jejímiž prvky jsou reference na spojované datové rámce:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeE.tsv", sep="\t")
df2 = pandas.read_csv("tiobeF.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
concatenated = pandas.concat([df1, df2], axis=1)
 
# výpis výsledku
print(concatenated)

Příklad nejdříve vypíše obsah původních datových rámců:

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

Poté se vypíše obsah rámce získaného funkcí concat:

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

Spojení po řádcích je nepatrně jednodušší, neboť není zapotřebí specifikovat hodnotu nepovinného parametru axis:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeC.tsv", sep="\t")
df2 = pandas.read_csv("tiobeD.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
concatenated = pandas.concat([df1, df2])
 
# výpis výsledku
print(concatenated)

Příklad opět vypíše obsah původních rámců:

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

A následně rámec získaný spojením přes index:

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

9. Funkce merge

Velmi často se setkáme s nutností spojit dvě tabulky, které sice obsahují shodné sloupce, ovšem ne všechny řádky (resp. záznamy) nalezneme v obou spojovaných tabulkách. Taková operace je zcela běžná v oblasti relačních databází (přesněji řečeno v SQL databázích), kde pro ni existuje i klauzule JOIN. Podle toho, jakým způsobem jsou do výsledku zařazeny ty záznamy, které nejsou nalezeny v obou spojovaných tabulkách, rozlišujeme:

  1. vnitřní spojení (inner join)
  2. vnější spojení (outer join)

Vnější spojení je dále děleno na:

  1. úplně vnější spojení (outer join)
  2. vnější spojení zleva (left join)
  3. vnější spojení zprava (right join)

Tato operace je v knihovně Pandas realizována funkcí nazvanou merge; současně se jedná o jednu z funkcí, která dokáže do značné míry konfigurovat přesný postup operace spojení dvou datových rámců:

merge(left, right, how:str='inner', on=None, left_on=None, right_on=None, left_index:bool=False, right_index:bool=False, sort:bool=False, suffixes=('_x', '_y'), copy:bool=True, indicator:bool=False, validate=None) -> 'DataFrame'
    Merge DataFrame or named Series objects with a database-style join.
 
    The join is done on columns or indexes. If joining columns on
    columns, the DataFrame indexes *will be ignored*. Otherwise if joining indexes
    on indexes or indexes on a column or columns, the index will be passed on.
 
    Parameters
    ----------
    left : DataFrame
    right : DataFrame or named Series
        Object to merge with.
    how : {'left', 'right', 'outer', 'inner'}, default 'inner'
        Type of merge to be performed.
 
        * left: use only keys from left frame, similar to a SQL left outer join;
          preserve key order.
        * right: use only keys from right frame, similar to a SQL right outer join;
          preserve key order.
        * outer: use union of keys from both frames, similar to a SQL full outer
          join; sort keys lexicographically.
        * inner: use intersection of keys from both frames, similar to a SQL inner
          join; preserve the order of the left keys.
    on : label or list
        Column or index level names to join on. These must be found in both
        DataFrames. If `on` is None and not merging on indexes then this defaults
        to the intersection of the columns in both DataFrames.
    left_on : label or list, or array-like
        Column or index level names to join on in the left DataFrame. Can also
        be an array or list of arrays of the length of the left DataFrame.
        These arrays are treated as if they are columns.
    right_on : label or list, or array-like
        Column or index level names to join on in the right DataFrame. Can also
        be an array or list of arrays of the length of the right DataFrame.
        These arrays are treated as if they are columns.
    left_index : bool, default False
        Use the index from the left DataFrame as the join key(s). If it is a
        MultiIndex, the number of keys in the other DataFrame (either the index
    right_index : bool, default False
        Use the index from the right DataFrame as the join key. Same caveats as
        left_index.
    sort : bool, default False
        Sort the join keys lexicographically in the result DataFrame. If False,
        the order of the join keys depends on the join type (how keyword).
    suffixes : list-like, default is ("_x", "_y")
        A length-2 sequence where each element is optionally a string
        indicating the suffix to add to overlapping column names in
        `left` and `right` respectively. Pass a value of `None` instead
        of a string to indicate that the column name from `left` or
        `right` should be left as-is, with no suffix. At least one of the
        values must not be None.
    copy : bool, default True
        If False, avoid copy if possible.
    indicator : bool or str, default False
        If True, adds a column to the output DataFrame called "_merge" with
        information on the source of each row. The column can be given a different
        name by providing a string argument. The column will have a Categorical
        type with the value of "left_only" for observations whose merge key only
        appears in the left DataFrame, "right_only" for observations
        whose merge key only appears in the right DataFrame, and "both"
        if the observation's merge key is found in both DataFrames.

Vzhledem k velké univerzálnosti této funkce si ukážeme její použití na sedmici demonstračních příkladů. Použijeme přitom datové rámce, které vzniknou načtením dvojice tabulek, které mají některé řádky shodné a jiné naopak chybí.

V první tabulce je patnáct řádků původně získaných z Tiobe indexu:

Sep 2019       Change        Language           Ratings        Changep
2              change        C                  15.95          +0.74
1              change        Java               13.48          -3.18
3                            Python             10.47          +0.59
4                            C++                7.11           +1.48
5                            C#                 4.58           +1.18
6                            Visual Basic       4.12           +0.83
7                            JavaScript         2.54           +0.41
9              change        PHP                2.49           +0.62
19             change        R                  2.37           +1.33
8              change        SQL                1.76           -0.19
14             change        Go                 1.46           +0.24
16             change        Swift              1.38           +0.28
20             change        Perl               1.30           +0.26
12             change        Assembly language  1.30           -0.08
15                           Ruby               1.24           +0.03

Ve druhé tabulce je taktéž patnáct řádků původně získaných z Tiobe indexu, ovšem posledních pět řádků je od předchozí tabulky odlišných:

Sep 2020       Change        Language           Ratings        Changep
1              change        C                  15.95          +0.74
2              change        Java               13.48          -3.18
3                            Python             10.47          +0.59
4                            C++                7.11           +1.48
5                            C#                 4.58           +1.18
6                            Visual Basic       4.12           +0.83
7                            JavaScript         2.54           +0.41
8              change        PHP                2.49           +0.62
9              change        R                  2.37           +1.33
10             change        SQL                1.76           -0.19
16             change        MATLAB             1.10           +0.04
17             change        Groovy             0.99           -0.52
18             change        Rust               0.92           +0.55
19             change        Objective-C        0.85           -0.99
20             change        Dart               0.77           +0.13

10. Inner join (vnitřní spojení) založený na funkci merge

Operace vnitřního spojení neboli inner join dokáže automaticky spojit ty řádky tabulek, které mají totožný obsah. Současně jsou i identifikovány sloupce se shodným názvem a typem (pokud neurčíme jinak). Podívejme se nyní na způsob provedení této operace u datových rámců, které mají implicitní (celočíselné) indexy:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2)
 
# výpis výsledku
print(merged)

Výsledný datový rámec obsahuje pouze deset řádků obsažených v levém i pravém rámci vstupujícím do operace JOIN:

   Sep 2019  Change      Language  Ratings  Changep  Sep 2020
0         2  change             C    15.95     0.74         1
1         1  change          Java    13.48    -3.18         2
2         3     NaN        Python    10.47     0.59         3
3         4     NaN           C++     7.11     1.48         4
4         5     NaN            C#     4.58     1.18         5
5         6     NaN  Visual Basic     4.12     0.83         6
6         7     NaN    JavaScript     2.54     0.41         7
7         9  change           PHP     2.49     0.62         8
8        19  change             R     2.37     1.33         9
9         8  change           SQL     1.76    -0.19        10

Spojení dvou datových rámců s explicitně nastavenými indexy získanými ze sloupce „Language“:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2)
 
# výpis výsledku
print(merged)

Povšimněte si, že v tomto případě (ovšem i v příkladu předchozím!) došlo k odstranění původních indexů – ty byly nahrazeny indexem celočíselným založeným na generátoru range:

   Sep 2019  Change  Ratings  Changep  Sep 2020
0         2  change    15.95     0.74         1
1         1  change    13.48    -3.18         2
2         3     NaN    10.47     0.59         3
3         4     NaN     7.11     1.48         4
4         5     NaN     4.58     1.18         5
5         6     NaN     4.12     0.83         6
6         7     NaN     2.54     0.41         7
7         9  change     2.49     0.62         8
8        19  change     2.37     1.33         9
9         8  change     1.76    -0.19        10

Použití indexů si ovšem můžeme vynutit nepovinnými parametry left_index a right_index nastavenými na hodnotu True:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2, left_index=True, right_index=True)
 
# výpis výsledku
print(merged)

Nyní bude výsledek velmi odlišný, protože bude obsahovat dvojnásobné množství sloupců – ovšem datové rámce budou korektně spojeny na základě indexů:

              Sep 2019 Change_x  Ratings_x  ...  Change_y  Ratings_y Changep_y
Language
C                    2   change      15.95  ...    change      15.95      0.74
Java                 1   change      13.48  ...    change      13.48     -3.18
Python               3      NaN      10.47  ...       NaN      10.47      0.59
C++                  4      NaN       7.11  ...       NaN       7.11      1.48
C#                   5      NaN       4.58  ...       NaN       4.58      1.18
Visual Basic         6      NaN       4.12  ...       NaN       4.12      0.83
JavaScript           7      NaN       2.54  ...       NaN       2.54      0.41
PHP                  9   change       2.49  ...    change       2.49      0.62
R                   19   change       2.37  ...    change       2.37      1.33
SQL                  8   change       1.76  ...    change       1.76     -0.19
 
[10 rows x 8 columns]

Předchozí demonstrační příklad lze rozšířit specifikací těch sloupců, které se skutečně mají spojit. To zařizuje nepovinný parametr on (což opět připomíná SQL konstrukci JOIN xxx ON):

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2, left_index=True, right_index=True,
                      on=["Change", "Ratings", "Changep"])

# výpis výsledku
print(merged)

Výsledek se asi nejvíce blíží ideálu – jsou zachovány indexy a současně nedošlo ke zdvojení všech sloupců v datovém rámci:

              Sep 2019  Change  Ratings  Changep  Sep 2020
Language
C                    2  change    15.95     0.74         1
Java                 1  change    13.48    -3.18         2
Python               3     NaN    10.47     0.59         3
C++                  4     NaN     7.11     1.48         4
C#                   5     NaN     4.58     1.18         5
Visual Basic         6     NaN     4.12     0.83         6
JavaScript           7     NaN     2.54     0.41         7
PHP                  9  change     2.49     0.62         8
R                   19  change     2.37     1.33         9
SQL                  8  change     1.76    -0.19        10
Poznámka: pro úplnost si ještě můžete vyzkoušet co se stane ve chvíli, kdy v levém nebo pravém datovém rámci chybí celý sloupec.

11. Left join (vnější spojení „zleva“) založený na funkci merge

Ukažme si nyní způsob provedení vnějšího spojení dvou datových rámců zleva. Toto spojení je specifikováno parametrem how nastaveným na hodnotu „left“ (jedná se o řetězec). Ve výsledném datovém rámci budou za všech okolností všechny řádky z levého rámce, a to i ve chvíli, kdy k nim nebyly nalezeny odpovídající řádky v pravém rámci:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2, left_index=True, right_index=True,
                      how="left",
                      on=["Change", "Ratings", "Changep"])
 
# výpis výsledku
print(merged)

Ve výsledném datovém rámci je po spojení uloženo celkem patnáct řádků, protože byly přidány i všechny řádky z prvního (levého) datového rámce, které ovšem nemají všechny potřebné údaje ve sloupci Sep 2020. Proto je namísto těchto hodnot použita NaN („Not a Number“):

                   Sep 2019  Change  Ratings  Changep  Sep 2020
Language
C                         2  change    15.95     0.74       1.0
Java                      1  change    13.48    -3.18       2.0
Python                    3     NaN    10.47     0.59       3.0
C++                       4     NaN     7.11     1.48       4.0
C#                        5     NaN     4.58     1.18       5.0
Visual Basic              6     NaN     4.12     0.83       6.0
JavaScript                7     NaN     2.54     0.41       7.0
PHP                       9  change     2.49     0.62       8.0
R                        19  change     2.37     1.33       9.0
SQL                       8  change     1.76    -0.19      10.0
Go                       14  change     1.46     0.24       NaN
Swift                    16  change     1.38     0.28       NaN
Perl                     20  change     1.30     0.26       NaN
Assembly language        12  change     1.30    -0.08       NaN
Ruby                     15     NaN     1.24     0.03       NaN

12. Right join (vnější spojení „zprava“) založený na funkci merge

Následuje ukázka vnějšího spojení dvou datových rámců zprava. Toto spojení je specifikováno parametrem how nastaveným na hodnotu „right“ (opět se jedná o řetězec). Ve výsledném datovém rámci budou za všech okolností všechny řádky z pravého rámce, a to i ve chvíli, kdy k nim nebyly nalezeny odpovídající řádky v levém rámci:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2, left_index=True, right_index=True,
                      how="right",
                      on=["Change", "Ratings", "Changep"])
 
# výpis výsledku
print(merged)

Výsledný datový rámec bude (opět) obsahovat patnáct řádků, ale v tomto případě se jedná o odlišné řádky, než tomu bylo v příkladu předchozím:

              Sep 2019  Change  Ratings  Changep  Sep 2020
Language
C                  2.0  change    15.95     0.74         1
Java               1.0  change    13.48    -3.18         2
Python             3.0     NaN    10.47     0.59         3
C++                4.0     NaN     7.11     1.48         4
C#                 5.0     NaN     4.58     1.18         5
Visual Basic       6.0     NaN     4.12     0.83         6
JavaScript         7.0     NaN     2.54     0.41         7
PHP                9.0  change     2.49     0.62         8
R                 19.0  change     2.37     1.33         9
SQL                8.0  change     1.76    -0.19        10
MATLAB             NaN     NaN      NaN      NaN        16
Groovy             NaN     NaN      NaN      NaN        17
Rust               NaN     NaN      NaN      NaN        18
Objective-C        NaN     NaN      NaN      NaN        19
Dart               NaN     NaN      NaN      NaN        20
Poznámka: chybějící hodnoty jsou doplněny na hodnotu NaN.

13. Outer join (vnější spojení) založený na funkci merge

Zbývá nám popis poslední varianty spojení datových rámců – plný outer join specifikovaný hodnotou „outer“ předanou do pojmenovaného parametru how:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = pandas.merge(df1, df2, left_index=True, right_index=True,
                      how="outer",
                      on=["Change", "Ratings", "Changep"])
 
# výpis výsledku
print(merged)

Nyní bude výsledný datový rámec obsahovat všech dvacet řádků, ovšem některé sloupce musely být doplněny hodnotami NaN:

                   Sep 2019  Change  Ratings  Changep  Sep 2020
Language
Assembly language      12.0  change     1.30    -0.08       NaN
C                       2.0  change    15.95     0.74       1.0
C#                      5.0     NaN     4.58     1.18       5.0
C++                     4.0     NaN     7.11     1.48       4.0
Dart                    NaN  change     0.77     0.13      20.0
Go                     14.0  change     1.46     0.24       NaN
Groovy                  NaN  change     0.99    -0.52      17.0
Java                    1.0  change    13.48    -3.18       2.0
JavaScript              7.0     NaN     2.54     0.41       7.0
MATLAB                  NaN  change     1.10     0.04      16.0
Objective-C             NaN  change     0.85    -0.99      19.0
PHP                     9.0  change     2.49     0.62       8.0
Perl                   20.0  change     1.30     0.26       NaN
Python                  3.0     NaN    10.47     0.59       3.0
R                      19.0  change     2.37     1.33       9.0
Ruby                   15.0     NaN     1.24     0.03       NaN
Rust                    NaN  change     0.92     0.55      18.0
SQL                     8.0  change     1.76    -0.19      10.0
Swift                  16.0  change     1.38     0.28       NaN
Visual Basic            6.0     NaN     4.12     0.83       6.0

14. Použití metody join pro spojení dvou datových rámců

Namísto funkce merge, která dokáže spojit dva datové rámce, které jsou jí předány formou parametrů, existuje i metoda objektů typu DataFrame, která se jmenuje join:

join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
-> 'DataFrame' method of pandas.core.frame.DataFrame instance
 
    Join columns of another DataFrame.
 
    Join columns with `other` DataFrame either on index or on a key
    column. Efficiently join multiple DataFrame objects by index at once by
    passing a list.

Po funkční stránce se jedná o zjednodušenou variantu funkce merge, protože opět dojde ke spojení rámců s využitím zvolené varianty, ovšem některé parametry chybí, resp. nedávají v daném kontextu smysl. Implicitně je zjištění korespondujících řádků obou spojovaných datových rámců zajištěno na základě indexů.

15. Inner join (vnitřní spojení) založený na metodě join

Způsob použití metody join si nejdříve ukážeme na příkladu vnitřního spojení, tedy na operaci nazývané inner join. Použijeme, podobně jako v předchozích demonstračních příkladech, datové soubory „tiobeA.tsv“ a „tiobeB.tsv“. Povšimněte si specifikace suffixů, které budou přidány ke jménům sloupců:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = df1.join(df2, how="inner", lsuffix="_left", rsuffix="_right")
 
# výpis výsledku
print(merged)

Výsledkem bude nový datový rámec s deseti řádky a osmi sloupci – sloupce z prvního rámce tedy nejsou spojeny se sloupci z rámce druhého a odlišeny jsou názvem (resp. suffixem v názvu):

              Sep 2019 Change_left  ...  Ratings_right  Changep_right
Language
C                    2      change  ...          15.95           0.74
Java                 1      change  ...          13.48          -3.18
Python               3         NaN  ...          10.47           0.59
C++                  4         NaN  ...           7.11           1.48
C#                   5         NaN  ...           4.58           1.18
Visual Basic         6         NaN  ...           4.12           0.83
JavaScript           7         NaN  ...           2.54           0.41
PHP                  9      change  ...           2.49           0.62
R                   19      change  ...           2.37           1.33
SQL                  8      change  ...           1.76          -0.19
 
[10 rows x 8 columns]

16. Left join (vnější spojení „zleva“) založený na metodě join

Vnější spojení dvou datových rámců zleva neboli left join se opět provede metodou join, ovšem lišit se bude parametr how. Ostatní části demonstračního příkladu zůstanou nezměněné:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = df1.join(df2, how="left", lsuffix="_left", rsuffix="_right")
 
# výpis výsledku
print(merged)

Opět vznikne datový rámec s dvojnásobným množstvím sloupců, ovšem důležitější je, že nyní obsahuje 15 řádků – přidány byly ty řádky z levého datového rámce, které neexistují v rámci pravém:

                   Sep 2019 Change_left  ...  Ratings_right  Changep_right
Language
C                         2      change  ...          15.95           0.74
Java                      1      change  ...          13.48          -3.18
Python                    3         NaN  ...          10.47           0.59
C++                       4         NaN  ...           7.11           1.48
C#                        5         NaN  ...           4.58           1.18
Visual Basic              6         NaN  ...           4.12           0.83
JavaScript                7         NaN  ...           2.54           0.41
PHP                       9      change  ...           2.49           0.62
R                        19      change  ...           2.37           1.33
SQL                       8      change  ...           1.76          -0.19
Go                       14      change  ...            NaN            NaN
Swift                    16      change  ...            NaN            NaN
Perl                     20      change  ...            NaN            NaN
Assembly language        12      change  ...            NaN            NaN
Ruby                     15         NaN  ...            NaN            NaN
 
[15 rows x 8 columns]

17. Right join (vnější spojení „zprava“) založený na metodě join

Pochopitelně si ukážeme i způsob provedení vnějšího spojení dvou datových rámců zprava, tedy right join. Samotný zdrojový kód demonstračního příkladu se bude lišit pouze odlišnou hodnotou parametru how předaného metodě join:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = df1.join(df2, how="right", lsuffix="_left", rsuffix="_right")
 
# výpis výsledku
print(merged)

Výsledek nyní bude obsahovat patnáct řádků, protože do výsledného rámce byly přidány i ty řádky, které existují pouze v pravém (druhém) datovém rámci. Ty řádky, které existují pouze v levém rámci, nejsou do výsledku zařazeny:

              Sep 2019 Change_left  ...  Ratings_right  Changep_right
Language
C                  2.0      change  ...          15.95           0.74
Java               1.0      change  ...          13.48          -3.18
Python             3.0         NaN  ...          10.47           0.59
C++                4.0         NaN  ...           7.11           1.48
C#                 5.0         NaN  ...           4.58           1.18
Visual Basic       6.0         NaN  ...           4.12           0.83
JavaScript         7.0         NaN  ...           2.54           0.41
PHP                9.0      change  ...           2.49           0.62
R                 19.0      change  ...           2.37           1.33
SQL                8.0      change  ...           1.76          -0.19
MATLAB             NaN         NaN  ...           1.10           0.04
Groovy             NaN         NaN  ...           0.99          -0.52
Rust               NaN         NaN  ...           0.92           0.55
Objective-C        NaN         NaN  ...           0.85          -0.99
Dart               NaN         NaN  ...           0.77           0.13
 
[15 rows x 8 columns]

18. Outer join (vnější spojení) založený na metodě join

Poslední formou spojení dvou datových rámců je úplné vnější spojení neboli outer join. Opět si ukážeme, jakým způsobem se tato operace provádí:

#!/usr/bin/env python3
# vim: set fileencoding=utf-8
 
import pandas
 
# přečtení zdrojových dat
df1 = pandas.read_csv("tiobeA.tsv", sep="\t")
df2 = pandas.read_csv("tiobeB.tsv", sep="\t")
 
# specifikace indexu - má se získat ze sloupce Language
df1.set_index("Language", inplace=True)
df2.set_index("Language", inplace=True)
 
# datové rámce zobrazíme
print(df1)
print()
print(df2)
print()
 
# spojení obou datových rámců
merged = df1.join(df2, how="outer", lsuffix="_left", rsuffix="_right")
 
# výpis výsledku
print(merged)

Nyní bude výsledný datový rámec obsahovat všech dvacet řádků, přičemž některé řádky jsou získány z obou datových rámců a další existují pouze v rámci levém nebo naopak v rámci pravém:

DT2021 tip

                   Sep 2019 Change_left  ...  Ratings_right  Changep_right
Language
Assembly language      12.0      change  ...            NaN            NaN
C                       2.0      change  ...          15.95           0.74
C#                      5.0         NaN  ...           4.58           1.18
C++                     4.0         NaN  ...           7.11           1.48
Dart                    NaN         NaN  ...           0.77           0.13
Go                     14.0      change  ...            NaN            NaN
Groovy                  NaN         NaN  ...           0.99          -0.52
Java                    1.0      change  ...          13.48          -3.18
JavaScript              7.0         NaN  ...           2.54           0.41
MATLAB                  NaN         NaN  ...           1.10           0.04
Objective-C             NaN         NaN  ...           0.85          -0.99
PHP                     9.0      change  ...           2.49           0.62
Perl                   20.0      change  ...            NaN            NaN
Python                  3.0         NaN  ...          10.47           0.59
R                      19.0      change  ...           2.37           1.33
Ruby                   15.0         NaN  ...            NaN            NaN
Rust                    NaN         NaN  ...           0.92           0.55
SQL                     8.0      change  ...           1.76          -0.19
Swift                  16.0      change  ...            NaN            NaN
Visual Basic            6.0         NaN  ...           4.12           0.83
 
[20 rows x 8 columns]

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
       
61 series21_map.py postupná aplikace vybrané funkce na všechny prvky datové řady (lambda) https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries21_map.py
62 series22_map.py postupná aplikace vybrané funkce na všechny prvky datové řady (reference na funkci) https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries22_map.py
63 series23_map.py použití slovníku ve funkci mapy https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries23_map.py
64 series24_map.py použití slovníku ve funkci mapy (zkrácená varianta) https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries24_map.py
65 series25_transform.py transformace dat v datové řadě s využitím metody transform https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries25_transform.py
66 series26_transform.py vytvoření více sloupců s transformovanými daty https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries26_transform.py
67 series27_transform.py vytvoření více sloupců s transformovanými daty https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries27_transform.py
68 series28_transform.py použití jmen funkcí ve formě řetězců https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries28_transform.py
69 series29_agg.py agregace informací z datové řady: metoda agg https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries29_agg.py
70 series30_agg.py použití jmen funkcí namísto jejich referencí: metoda agg https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries30_agg.py
71 series31_aggregate.py agregace informací z datové řady: metoda aggregate https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries31_aggregate.py
72 series32_aggregate.py použití jmen funkcí namísto jejich referencí: metoda aggregate https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries32_aggregate.py
73 series33_combine.py kombinace údajů ze dvou datových řad popř. datové řady a skalární hodnoty https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries33_combine.py
74 series34_mask.py výběr hodnot na základě zadané podmínky metodou mask https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries34_mask.py
75 series35_mask_inplace_true.py vliv nepovinného parametru inplace na metodu mask https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries35_mask_inplace_true.py
76 series36_mask_inplace_false.py vliv nepovinného parametru inplace na metodu mask https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries36_mask_inplace_false­.py 
77 series37_where.py výběr hodnot na základě zadané podmínky metodou where https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries37_where.py
78 series38_where_inplace_true.py vliv nepovinného parametru inplace na metodu where https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries38_where_inplace_true­.py
79 series39_where_inplace_false.py vliv nepovinného parametru inplace na metodu where https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries39_where_inplace_false­.py
80 series40_where_drop.py skutečná filtrace dat kombinující wheredropna https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries40_where_drop.py
81 series41_mask_drop.py alternativní způsob založený na kombinaci maskdropna https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries41_mask_drop.py
82 series42_group_by.py jedna z variant metody groupby aplikovaná na datovou řadu https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries42_group_by.py
       
83 series_items.py iterace přes všechny prvky datové řady založená na metodě items https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries_items.py
84 series_iteritems.py iterace přes všechny prvky datové řady založená na metodě iteritems https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/se­ries_iteritems.py
       
85 data_frame01_loading.py načtení datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame01_loading.py
86 data_frame02_map_conversion.py postupná aplikace vybrané funkce na všechny prvky sloupce datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame02_map_conversion­.py
87 data_frame03_map_conversion.py postupná aplikace vybrané funkce na všechny prvky sloupce datového rámce https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame03_map_conversion­.py
88 data_frame04_map_format.py naformátování sloupce v datovém rámci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame04_map_format.py
89 data_frame05_transform_conversion.py transformace dat ve sloupci datového rámce s využitím metody transform https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame05_transform_conver­sion.py
90 data_frame06_transform_conversion.py transformace dat ve sloupci datového rámce s využitím metody transform https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame06_transform_conver­sion.py
91 data_frame07_transform_format.py naformátování sloupce v datovém rámci https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame07_transform_format­.py
92 data_frame08_aggregate.py agregace informací ze sloupce datového rámce: metoda aggregate https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame08_aggregate.py
93 data_frame09_aggregate.py použití jmen funkcí namísto jejich referencí: metoda aggregate https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame09_aggregate.py
94 data_frame10_combine.py kombinace údajů ze dvou sloupců datových rámců popř. datové řady a skalární hodnoty https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame10_combine.py
95 data_frame_append.py připojení druhého datového rámce k rámci prvnímu metodou append https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_append.py
96 data_frame_concat_by_columns.py spojení dvou datových rámců po sloupcích funkcí concat https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_concat_by_columns­.py
97 data_frame_concat_by_rows.py spojení dvou datových rámců po řádcích funkcí concat https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_concat_by_rows.py
98 data_frame_join01_inner_join.py inner join (vnitřní spojení) založený na metodě join https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_join01_inner_join­.py
99 data_frame_join02_left_join.py left join (vnější spojení „zleva“) založený na metodě join https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_join02_left_join­.py
100 data_frame_join03_right_join.py right join (vnější spojení „zprava“) založený na metodě join https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_join03_right_join­.py
101 data_frame_join04_outer_join.py outer join (vnější spojení) založený na metodě join https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_join04_outer_join­.py
102 data_frame_merge01_inner_join.py inner join (vnitřní spojení) založený na funkci merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge01_inner_jo­in.py
103 data_frame_merge02_inner_jo­in_ignore_indexes.py ignorování indexů při spojování datových rámců funkcí merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge02_inner_jo­in_ignore_indexes.py
104 data_frame_merge03_inner_jo­in_use_indexes.py použití indexů při spojování datových rámců funkcí merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge03_inner_jo­in_use_indexes.py
105 data_frame_merge04_inner_jo­in_use_indexes.py použití indexů při spojování datových rámců funkcí merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge04_inner_jo­in_use_indexes.py
106 data_frame_merge05_left_join.py left join (vnější spojení „zleva“) založený na funkci merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge05_left_join­.py
107 data_frame_merge06_right_join.py right join (vnější spojení „zprava“) založený na funkci merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge06_right_jo­in.py
108 data_frame_merge07_outer_join.py outer join (vnější spojení) založený na funkci merge https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/da­ta_frame_merge07_outer_jo­in.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
       
10 tiobeA.tsv tabulka z tiobe.tsv, ovšem pět řádků bylo odstraněno https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeA.tsv
11 tiobeB.tsv tabulka z tiobe.tsv, ovšem pět (jiných) řádků bylo odstraněno https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeB.tsv
12 tiobeC.tsv prvních deset řádků z tabulky „tiobe.tsv“ https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeC.tsv
13 tiobeD.tsv posledních deset řádků z tabulky „tiobe.tsv“ https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeD.tsv
14 tiobeE.tsv tři sloupce z tabulky „tiobe.tsv“ https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeE.tsv
15 tiobeF.tsv čtyři sloupce z tabulky „tiobe.tsv“ https://github.com/tisnik/most-popular-python-libs/blob/master/pandas/tiobeF.tsv

20. Odkazy na Internetu

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

Autor článku

Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.