File size: 5,739 Bytes
2a6b09f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import pandas as pd
import streamlit as st
import plotly.express as px
import numpy as np
import scipy.stats as stats

# Elegant and Centered Title
st.markdown(
    """

    <h1 style='text-align: center; color: red;'>Tips Dataset Explorer</h1>

    """,
    unsafe_allow_html=True
)

# Upload Section
file = st.file_uploader("๐Ÿ“‚ Upload a CSV file", type=["csv"])

if file is not None:
    df = pd.read_csv(file)
    st.markdown("### ๐Ÿงพ Preview of the Dataset:")
    st.write(df.head())

    categorical_cols = df.select_dtypes(include='object').columns.tolist()
    numerical_cols = df.select_dtypes(include=['int64', 'float64']).columns.tolist()

    st.markdown("## ๐Ÿ” Univariate Analysis")

    # ========================== #
    #      CATEGORICAL PART      #
    # ========================== #
    st.markdown("### ๐ŸŸจ Categorical Feature Analysis")

    selected_cat = st.selectbox("Select a categorical feature", categorical_cols, key='cat_feature')

    if selected_cat:
        col_data = df[selected_cat]
        st.write(f"**Feature: `{selected_cat}`**")
        st.write(f"๐Ÿ”ข Unique values: {col_data.unique()}")
        st.write(f"๐Ÿงฎ Number of unique values: {col_data.nunique()}")
        st.write(f"๐Ÿ“Œ Mode: {col_data.mode()[0]}")
        st.write(f"โ“ Missing values: {col_data.isnull().sum()}")

        value_counts = col_data.value_counts()
        proportion = (value_counts / len(df)).round(3) * 100

        st.write("๐Ÿ“Š Frequency Table:")
        freq_table = pd.DataFrame({ 'Count': value_counts, 'Percentage (%)': proportion })
        st.write(freq_table)

        # Entropy
        entropy = stats.entropy(value_counts)
        st.write(f"๐Ÿง  Entropy (uncertainty in distribution): `{entropy:.3f}`")

        # Charts
        st.write("๐Ÿ“Š Bar Chart:")
        st.bar_chart(value_counts)

        if st.checkbox("๐Ÿ“ˆ Show Pie Chart", key="pie_cat"):
            fig_pie = px.pie(names=value_counts.index, values=value_counts.values, 
                             title=f'Distribution of {selected_cat}')
            st.plotly_chart(fig_pie)

        # Cross-tab Heatmap
        other_cat = st.selectbox("Compare with another categorical feature", 
                                 [col for col in categorical_cols if col != selected_cat], key='cat_cross')
        if other_cat:
            cross_tab = pd.crosstab(df[selected_cat], df[other_cat])
            st.markdown(f"### ๐Ÿ” Cross-tabulation: `{selected_cat}` vs `{other_cat}`")
            st.dataframe(cross_tab.style.background_gradient(cmap='viridis'))

    # ========================== #
    #      NUMERICAL PART        #
    # ========================== #
    st.markdown("### ๐ŸŸฆ Numerical Feature Analysis")

    selected_num = st.selectbox("Select a numerical feature", numerical_cols, key='num_feature')

    if selected_num:
        col_data = df[selected_num].dropna()

        st.write(f"**Feature: `{selected_num}`**")
        st.write(f"๐Ÿ“ Mean: {col_data.mean():.2f}")
        st.write(f"๐Ÿช™ Median: {col_data.median():.2f}")
        st.write(f"๐Ÿ“‰ Min: {col_data.min()} | ๐Ÿ“ˆ Max: {col_data.max()}")
        st.write(f"๐Ÿ“Š Std: {col_data.std():.2f} | ๐Ÿ“ Variance: {col_data.var():.2f}")
        st.write(f"๐Ÿ“ˆ Skewness: {col_data.skew():.2f} | ๐Ÿ”บ Kurtosis: {col_data.kurt():.2f}")
        st.write(f"โ“ Missing Values: {df[selected_num].isnull().sum()}")

        # Quartiles
        Q1 = col_data.quantile(0.25)
        Q2 = col_data.quantile(0.50)
        Q3 = col_data.quantile(0.75)
        IQR = Q3 - Q1
        st.write(f"๐Ÿ”ข Quartiles: Q1={Q1:.2f}, Q2={Q2:.2f}, Q3={Q3:.2f}, IQR={IQR:.2f}")

        # Outliers based on Z-score
        z_scores = np.abs(stats.zscore(col_data))
        outliers = (z_scores > 3).sum()
        st.write(f"๐Ÿšจ Outliers (Z-score > 3): {outliers}")

        # Distribution Plot
        st.write("๐Ÿ“Š Distribution (Histogram):")
        fig_hist = px.histogram(df, x=selected_num, nbins=30, title=f'Distribution of {selected_num}')
        st.plotly_chart(fig_hist)

        # Box Plot
        st.write("๐Ÿ“ฆ Box Plot:")
        fig_box = px.box(df, y=selected_num, title=f'Box Plot of {selected_num}')
        st.plotly_chart(fig_box)

        # KDE Plot Option
        if st.checkbox("๐Ÿ“ˆ Show KDE (Density Estimation)", key='kde'):
            fig_kde = px.histogram(df, x=selected_num, nbins=30, marginal="violin", title=f'KDE of {selected_num}')
            st.plotly_chart(fig_kde)

        # Binning
        if st.checkbox("๐ŸงŠ Show Value Bins", key='bins'):
            bins = st.slider("Number of bins", min_value=2, max_value=20, value=5)
            binned_col = pd.cut(col_data, bins=bins)
            bin_counts = binned_col.value_counts().sort_index()
            st.write(bin_counts)

            fig_bin_pie = px.pie(names=bin_counts.index.astype(str), values=bin_counts.values,
                                 title=f'Binned Distribution of {selected_num}')
            st.plotly_chart(fig_bin_pie)

        # Log Transformation Preview
        if st.checkbox("๐Ÿ”„ Preview Log Transformation", key='log_transform'):
            df['log_' + selected_num] = np.log1p(col_data)
            fig_log = px.histogram(df, x='log_' + selected_num, nbins=30, 
                                   title=f'Log-Transformed Histogram of {selected_num}')
            st.plotly_chart(fig_log)

    # Summary Table
    st.markdown("### ๐Ÿ“‹ Summary Statistics")
    st.dataframe(df[numerical_cols].describe().T.style.background_gradient(cmap='Blues'))

else:
    st.warning("๐Ÿ“ Please upload a CSV file to begin analysis.")