Jak pracovat s datovou sadou Faktury Ministerstva financí

Aktualizováno: 19. 7. 2021 Autor: Tomáš Vitvar Zdrojový kód: GitHub

Upozornění: Tento dokument slouží jako příklad práce s otevřenými daty a nepředstavuje oficiální stanovisko Ministerstva financí.

Úvod

Pod tématem Hospodaření Ministerstva financí na našem portálu lze najít celkem šest datových sad, z nichž snad nejzajímavější je přehled uhrazených faktur. Právě této datové sadě se v tomto krátkém článku budeme věnovat, zatímco se budeme pokoušet nastínit základní specifika této datové sady, které uživatel nemůže při jejím zpracování opomenout. Kde se nám tak zdálo vhodné, doplňuje text názorná ukázka možného zpracování dat v programovacím jazyce Python za použití balíčku Pandas.

Denormalizovaná data

Uživatel si musí být především vědom, že tato datová sada vznikla denormalizací dat, která jsou jinak v tradičním, relačním modelu (v relační databázi) uložena ve dvou tabulkách. Těmi jsou celkový přehled faktur a k němu příslušné dělení dle položky rozpočtu. Jak to vypadá v praxi, lze vyčíst z letmého pohledu na prvních několik řádků.

In [1]:
import pandas as pd

dtype = {"dodavatel_ičo" : "str", "položka_rozpočtu" : "str", "účel_platby" : "str"}

faktury = pd.read_csv("https://opendata.mfcr.cz/exports/faktury/faktury.csv", dtype = dtype)
In [2]:
faktury.sort_values(by = ["částka", "číslo_faktury", "typ_záznamu"], ascending = False).head()
Out[2]:
typ_záznamu iri dodavatel_ičo dodavatel_název typ_dokladu částka částka_bez_dph částka_v_měně měna datum_vystavení datum_přijetí datum_splatnosti datum_úhrady částka_k_úhradě částka_k_úhradě_v_měně účel_platby položka_rozpočtu název_položky_rozpočtu částka_za_položku_rozpočtu číslo_faktury
137589 souhrnný https://opendata.mfcr.cz/lod/faktury/1000001258 14890992 IBM Česká republika, spol. s r.o. F 205128831.6 205128831.6 205128831.6 CZK 2010-03-24T00:00:00.000Z 2010-03-25T00:00:00.000Z 2010-04-15T00:00:00.000Z 2010-03-31T00:00:00.000Z 205128831.6 205128831.6 NaN NaN NaN NaN 1000001258
137590 položkový https://opendata.mfcr.cz/lod/faktury/100000125... 14890992 IBM Česká republika, spol. s r.o. F 205128831.6 205128831.6 205128831.6 CZK 2010-03-24T00:00:00.000Z 2010-03-25T00:00:00.000Z 2010-04-15T00:00:00.000Z 2010-03-31T00:00:00.000Z 205128831.6 205128831.6 NaN 6111 Programové vybavení 205128831.6 1000001258
126316 souhrnný https://opendata.mfcr.cz/lod/faktury/1099900086 14890992 IBM Česká republika, spol. s r.o. F 157715251.2 157715251.2 157715251.2 CZK 2009-12-18T00:00:00.000Z 2011-01-12T00:00:00.000Z 2011-01-10T00:00:00.000Z 2011-01-18T00:00:00.000Z 157715251.2 157715251.2 NaN NaN NaN NaN 1099900086
126317 položkový https://opendata.mfcr.cz/lod/faktury/109990008... 14890992 IBM Česká republika, spol. s r.o. F 157715251.2 157715251.2 157715251.2 CZK 2009-12-18T00:00:00.000Z 2011-01-12T00:00:00.000Z 2011-01-10T00:00:00.000Z 2011-01-18T00:00:00.000Z 157715251.2 157715251.2 NaN 6111 Programové vybavení 157715251.2 1099900086
124707 souhrnný https://opendata.mfcr.cz/lod/faktury/1100000821 14890992 IBM Česká republika, spol. s r.o. Z 150000000.0 150000000.0 150000000.0 CZK 2011-03-01T00:00:00.000Z 2011-03-08T00:00:00.000Z 2011-03-29T00:00:00.000Z 2011-03-29T00:00:00.000Z 150000000.0 150000000.0 NaN NaN NaN NaN 1100000821

Zde vidíme, že ke každému souhrnnému záznamu (podle sloupce typ_záznamu) přísluší alespoň jeden (může jich být i více) záznam položkový. Jde-li nám o faktury nehledě na položku rozpočtu, můžeme tyto záznamy vynechat jednoduchým filtrem podle právě zmíněného sloupce.

Souhrnné záznamy

V takto vytvořené tabulce pak dává smysl počítat základní statistiky, jakými můžou být například počet faktur uhrazených v měsíci březnu roku 2021, či jejich celková částka (všimněme si, že na rozdíl od sloupce částka_v_měně odpovídají údaje ve sloupci částka vždy Kč).

In [3]:
faktury_souhrn = faktury[faktury["typ_záznamu"] == "souhrnný"]

brezen = ("2021-03-01" < faktury_souhrn["datum_úhrady"]) & (faktury_souhrn["datum_úhrady"] < "2021-04-01")

faktury_03_21 = faktury_souhrn[brezen]

def print_statistika(pocet, soucet_mil):
    print("Počet faktur: " + str(pocet))
    
    print("Částka v milionech Kč: " + "{:.0f}".format(soucet_mil))

pocet = len(faktury_03_21)

soucet_mil = sum(faktury_03_21["částka"])/10**6

print_statistika(pocet, soucet_mil)
Počet faktur: 436
Částka v milionech Kč: 103

Položkové záznamy

Pokud chceme naopak položku rozpočtu sledovat, můžeme analogicky vyfiltrovat záznamy položkové, případně můžeme v některých případech nechat tabulku tak, jak je, jelikož souhrnné záznamy nikdy položku rozpočtu obsahovat nebudou, jak se můžeme jednoduše přesvědčit.

In [4]:
len(faktury_souhrn.dropna(subset = ["položka_rozpočtu"])) == 0
Out[4]:
True

Budeme-li chtít kupříkladu spočíst stejné statistiky, jako v předchozím případě, avšak pouze pro položku rozpočtu Programové vybavení, uděláme to třeba takto.

In [5]:
brezen = ("2021-03-01" < faktury["datum_úhrady"]) & (faktury["datum_úhrady"] < "2021-04-01")
vybaveni = (faktury["název_položky_rozpočtu"] == "Programové vybavení")

faktury_03_21_PV = faktury[brezen & vybaveni]

pocet = len(faktury_03_21_PV)
            
soucet_mil = sum(faktury_03_21_PV["částka"])/10**6

print_statistika(pocet, soucet_mil)
Počet faktur: 2
Částka v milionech Kč: 9

O jaké faktury jde, můžeme zjistit následovně.

In [6]:
faktury_03_21_PV[["dodavatel_název", "částka", "účel_platby", "číslo_faktury"]]
Out[6]:
dodavatel_název částka účel_platby číslo_faktury
3267 ASD Software, s.r.o. 386425.0 Návrh, dodání a implementace IS APAO - Dodání ... 2100000463
3303 Státní pokladna Centrum sdílených služeb, s. p. 8178759.0 Smlouva o podpoře a rozvoji IISSP a poskytován... 2100000454

Závěr

Tolik tedy představení faktur, zbytek už je na Vás, na uživatelích našich otevřených dat.