Problem:
Porównujesz dwa zbiory danych: przed i po migracji. Wkraczasz w fazę budowania zaufania i wiarygodności. Okazało się, że nie wszystkie dane są jednakowe. Niektóre wymagają dodatkowej analizy i poprawek, a niektóre wyglądają lepiej w zmigrowanym datasecie. Na tyle lepiej, że trzeba je przedstawić biznesowi i pokazać na przykładach, że po migracji wyniki są lepsze.
W jaki sposób opisać te dane?
Rozwiązanie:
Jednym z pomysłów na rozwiązanie może być Streamlit. Przy jego pomocy dodasz komentarze, które potem będą służyły jako:
- Punkt do analizy i późniejszego ponownego sprawdzenia
- Przedstawisz je biznesowi jako dowód na poprawę jakości danych.
Streamlit data editor
Sercem całego rozwiązania jest Streamlit data_editor.
Definiujesz go jak zwykłą tabelę, ale zwraca on dataframa ze zmienionymi danymi.
To jest początek, podajesz dataframe, który będziesz edytował i jako wynik dostaniesz dataframe z komentarzami:
edited_df = st.data_editor(compared_df,
Do poprawnego zdefiniowania data edytora potrzebne będzie jeszcze column config, dzięki niemu określisz, jaką kolumnę można edytować a którą nie. Nie chcemy, żeby można było edytować kolumn z danymi:
"redesign": st.column_config.TextColumn(
"Redesign",
help="Redesign dataset value",
disabled=True
),
A chcemy dodać kolumnę z komentarzem, która będzie edytowalna:
'comment': st.column_config.TextColumn(
'Comment',
help='Should any action be taken?',
disabled=False
)
Streamlit session
Po edycji tego dataframa, dobrze zapisać go później do sesji.
st.session_state[SESSION_PARAM_EDITED_DF] = pd.DataFrame(edited_df)
Zapytasz dlaczego?
Kod streamlitowy wywoływane jest od góry do dołu. Gdy będziesz chciał pobrać i zapisać dane z dataframa wtedy, musisz pobrać go z sesji, inaczej nie będzie on jeszcze dostępny.
No właśnie, to jak zapisać edytowane dane?
Streamlit button save
Zdefiniowanie przycisku:
st.button('Save', on_click = save_modified_df)
Jak widzisz funkcja wywoływana po wciśnięciu przycisku nie ma żadnych parametrów. Więc musisz pobrać je z sesji. Następnie zapisać do pliku, u mnie wygląda to w ten sposób
def save_modified_df():
df = st.session_state[SESSION_PARAM_EDITED_DF]
base_dir = st.session_state[SESSION_PARAM_BASE_DIR]
unit_id = st.session_state[SESSION_PARAM_UNIT_ID]
save_csv(base_dir, f"{unit_id}.csv", df)
Natomiast aplikacji prezentuje się w ten sposób: