Created
December 30, 2025 17:56
-
-
Save JessicaWachtel/a211e642e810e660daf74f3ba0f38fbd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <title>Python CSV Analysis in the Browser</title> | |
| <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script> | |
| <style> | |
| body { | |
| font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif; | |
| padding: 2rem; | |
| max-width: 900px; | |
| margin: auto; | |
| } | |
| h1, h2 { | |
| margin-bottom: 0.5rem; | |
| } | |
| input, button, select { | |
| padding: 0.5rem; | |
| margin-top: 0.5rem; | |
| font-size: 1rem; | |
| } | |
| pre { | |
| background: #f6f8fa; | |
| padding: 1rem; | |
| overflow-x: auto; | |
| white-space: pre-wrap; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Python CSV Analysis in the Browser</h1> | |
| <p>This app uses Pyodide to run Python directly in the browser. Upload a CSV and explore it interactively.</p> | |
| <hr /> | |
| <h2>Upload a CSV File</h2> | |
| <input type="file" id="csv-file" accept=".csv" /> | |
| <pre id="data-output">Upload a CSV file to see results here…</pre> | |
| <h2> Explore a Column</h2> | |
| <label for="column-select">Choose column:</label> | |
| <select id="column-select"> | |
| <option value="">--Select--</option> | |
| </select> | |
| <pre id="column-output"></pre> | |
| <h2>Summary Statistics</h2> | |
| <pre id="summary-output"></pre> | |
| <script> | |
| async function main() { | |
| const pyodide = await loadPyodide(); | |
| await pyodide.loadPackage(["numpy", "pandas"]); | |
| // CSV file upload | |
| document.getElementById("csv-file").addEventListener("change", async (event) => { | |
| const file = event.target.files[0]; | |
| if (!file) return; | |
| const text = await file.text(); | |
| pyodide.globals.set("csv_text", text); | |
| pyodide.runPython(` | |
| import pandas as pd | |
| from io import StringIO | |
| from js import document | |
| # Load CSV | |
| df = pd.read_csv(StringIO(csv_text)) | |
| # Show first rows | |
| document.getElementById("data-output").innerText = df.head().to_string() | |
| # Populate column dropdown | |
| select = document.getElementById("column-select") | |
| select.innerHTML = "" | |
| option_default = document.createElement("option") | |
| option_default.value = "" | |
| option_default.text = "--Select--" | |
| select.appendChild(option_default) | |
| for col in df.columns: | |
| option = document.createElement("option") | |
| option.value = col | |
| option.text = col | |
| select.appendChild(option) | |
| # Show summary statistics | |
| summary_text = df.describe().to_string() | |
| document.getElementById("summary-output").innerText = summary_text | |
| `); | |
| }); | |
| // Column selection | |
| document.getElementById("column-select").addEventListener("change", (event) => { | |
| const column = event.target.value; | |
| pyodide.globals.set("selected_col", column); | |
| pyodide.runPython(` | |
| from js import document | |
| if selected_col: | |
| col_data = df[selected_col] | |
| document.getElementById("column-output").innerText = col_data.head().to_string() | |
| else: | |
| document.getElementById("column-output").innerText = "" | |
| `); | |
| }); | |
| } | |
| main(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment