File size: 3,659 Bytes
b0e7098
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9974dcb
b0e7098
 
 
 
 
 
 
 
3d12196
 
b0e7098
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e531db2
b0e7098
 
 
d60f697
50b7c9d
b0e7098
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import pandas as pd
import streamlit as st
from pandas.api.types import (
    is_categorical_dtype,
    is_datetime64_any_dtype,
    is_numeric_dtype,
    is_object_dtype,
)

def filter_dataframe(df: pd.DataFrame) -> pd.DataFrame:
    df = df.copy()

    # Tentar converter datas para um formato padrão (datetime, sem fuso horário)
    for col in df.columns:
        if is_object_dtype(df[col]):
            try:
                df[col] = pd.to_datetime(df[col])
            except Exception:
                pass

        if is_datetime64_any_dtype(df[col]):
            df[col] = df[col].dt.tz_localize(None)

    modification_container = st.container()

    with modification_container:
        to_filter_columns = st.multiselect("Filtrar por valor", [column for column in df.columns if column != 'id'], placeholder="Selecione um ou mais itens para filtrar")
        for column in to_filter_columns:
            left, right = st.columns((1, 20))
            left.write("↳")
            # Tratar colunas com < 10 valores únicos como categóricos
            if is_categorical_dtype(df[column]) or df[column].nunique() < 10:
                user_cat_input = right.multiselect(
                    f"Valores para {column}",
                    df[column].unique(),
                    default=[], # Lista vazia para não ter valores pré-selecionados
                    placeholder="Escolha uma opção"  
                )
                if user_cat_input:  # Filtrar apenas se houver seleção
                    df = df[df[column].isin(user_cat_input)]
            elif is_numeric_dtype(df[column]):
                _min = float(df[column].min())
                _max = float(df[column].max())
                step = (_max - _min) / 100
                user_num_input = right.slider(
                    f"Valores para {column}",
                    min_value=_min,
                    max_value=_max,
                    value=(_min, _max),
                    step=step,
                )
                df = df[df[column].between(*user_num_input)]
            elif is_datetime64_any_dtype(df[column]):
                user_date_input = right.date_input(
                    f"Valores para {column}",
                    value=(
                        df[column].min(),
                        df[column].max(),
                    ),
                    format="YYYY-MM-DD",
                )
                if len(user_date_input) == 2:
                    user_date_input = tuple(map(pd.to_datetime, user_date_input))
                    start_date, end_date = user_date_input
                    df = df.loc[df[column].between(start_date, end_date)]
            else:
                # Para colunas de texto, mostre uma seleção múltipla se houver poucos valores únicos
                unique_values = df[column].dropna().unique()
                if len(unique_values) < 1000:  # Ajuste o limite conforme necessário
                    user_text_input = right.multiselect(
                        f"Valores para {column}",
                        unique_values,
                        default=[],
                        placeholder="Escolha uma opção",  
                    )
                    if user_text_input:  # Filtrar apenas se houver seleção
                        df = df[df[column].isin(user_text_input)]
                else:
                    user_text_input = right.text_input(
                        f"Substring ou regex em {column}",
                    )
                    if user_text_input:
                        df = df[df[column].astype(str).str.contains(user_text_input, na=False)]

    return df