Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import io | |
| from utils import load_csv, get_file_info, filter_dataframe | |
| # Set page config | |
| st.set_page_config( | |
| page_title="CSV Viewer", | |
| page_icon="π", | |
| layout="wide" | |
| ) | |
| # Custom CSS for better styling | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| font-size: 2.5rem; | |
| font-weight: bold; | |
| color: #1f77b4; | |
| text-align: center; | |
| margin-bottom: 1rem; | |
| } | |
| .sub-header { | |
| font-size: 1.2rem; | |
| color: #666; | |
| text-align: center; | |
| margin-bottom: 2rem; | |
| } | |
| .file-info { | |
| background-color: #f0f2f6; | |
| padding: 1rem; | |
| border-radius: 0.5rem; | |
| margin-bottom: 1rem; | |
| } | |
| .anycoder-link { | |
| position: fixed; | |
| bottom: 10px; | |
| right: 10px; | |
| font-size: 0.8rem; | |
| color: #666; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| def main(): | |
| # Header | |
| st.markdown('<div class="main-header">CSV Viewer</div>', unsafe_allow_html=True) | |
| st.markdown('<div class="sub-header">Upload and explore your CSV files with ease</div>', unsafe_allow_html=True) | |
| # Anycoder attribution | |
| st.markdown('<div class="anycoder-link">Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a></div>', unsafe_allow_html=True) | |
| # File uploader | |
| uploaded_file = st.file_uploader( | |
| "Choose a CSV file", | |
| type=["csv"], | |
| help="Upload a CSV file to view and analyze its contents" | |
| ) | |
| if uploaded_file is not None: | |
| try: | |
| # Load the CSV file | |
| df = load_csv(uploaded_file) | |
| # Display file info | |
| file_info = get_file_info(df, uploaded_file.name) | |
| st.markdown(f""" | |
| <div class="file-info"> | |
| <strong>File:</strong> {file_info['filename']}<br> | |
| <strong>Rows:</strong> {file_info['rows']}<br> | |
| <strong>Columns:</strong> {file_info['columns']}<br> | |
| <strong>Size:</strong> {file_info['size']} | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Create tabs for different views | |
| tab1, tab2, tab3 = st.tabs(["π Data View", "π Statistics", "π Filter"]) | |
| with tab1: | |
| st.subheader("Data Preview") | |
| # Display options | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| rows_to_show = st.slider( | |
| "Number of rows to display", | |
| min_value=5, | |
| max_value=min(100, len(df)), | |
| value=min(10, len(df)) | |
| ) | |
| with col2: | |
| show_columns = st.multiselect( | |
| "Select columns to display", | |
| options=df.columns.tolist(), | |
| default=df.columns.tolist() | |
| ) | |
| # Display the dataframe | |
| if show_columns: | |
| st.dataframe( | |
| df[show_columns].head(rows_to_show), | |
| use_container_width=True, | |
| height=400 | |
| ) | |
| else: | |
| st.warning("Please select at least one column to display") | |
| # Download button | |
| csv = df.to_csv(index=False).encode('utf-8') | |
| st.download_button( | |
| label="Download CSV", | |
| data=csv, | |
| file_name="filtered_data.csv", | |
| mime="text/csv" | |
| ) | |
| with tab2: | |
| st.subheader("Data Statistics") | |
| if st.checkbox("Show summary statistics"): | |
| st.dataframe(df.describe(), use_container_width=True) | |
| if st.checkbox("Show data types"): | |
| st.write(df.dtypes) | |
| if st.checkbox("Show missing values"): | |
| missing_values = df.isnull().sum() | |
| st.write(missing_values[missing_values > 0]) | |
| with tab3: | |
| st.subheader("Filter Data") | |
| st.write("Filter your data based on column values") | |
| # Column selection for filtering | |
| filter_column = st.selectbox( | |
| "Select column to filter", | |
| options=df.columns.tolist() | |
| ) | |
| if filter_column: | |
| # Get unique values for the selected column | |
| unique_values = df[filter_column].unique() | |
| if len(unique_values) > 20: | |
| st.warning("This column has many unique values. Consider using a different filter method.") | |
| filter_method = st.radio( | |
| "Filter method", | |
| ["Range", "Contains"] | |
| ) | |
| if filter_method == "Range": | |
| min_val = st.number_input( | |
| "Minimum value", | |
| value=float(df[filter_column].min()) | |
| ) | |
| max_val = st.number_input( | |
| "Maximum value", | |
| value=float(df[filter_column].max()) | |
| ) | |
| if st.button("Apply Filter"): | |
| filtered_df = filter_dataframe(df, filter_column, min_val, max_val) | |
| st.dataframe(filtered_df, use_container_width=True) | |
| else: | |
| search_term = st.text_input("Contains text") | |
| if st.button("Apply Filter"): | |
| filtered_df = df[df[filter_column].astype(str).str.contains(search_term, case=False, na=False)] | |
| st.dataframe(filtered_df, use_container_width=True) | |
| else: | |
| selected_values = st.multiselect( | |
| "Select values to include", | |
| options=unique_values | |
| ) | |
| if st.button("Apply Filter"): | |
| filtered_df = df[df[filter_column].isin(selected_values)] | |
| st.dataframe(filtered_df, use_container_width=True) | |
| except Exception as e: | |
| st.error(f"Error processing file: {str(e)}") | |
| if __name__ == "__main__": | |
| main() |