In diesem Tutorial zeigen wir, wie man über statische, codelastige Diagramme hinausgeht und direkt mit ihnen einen wirklich interaktiven Workflow für die explorative Datenanalyse erstellt PyGWalker. Wir beginnen mit der Vorbereitung des Titanic-Datensatzes für umfangreiche interaktive Abfragen. Diese analysebereiten technischen Funktionen offenbaren die zugrunde liegende Struktur der Daten und ermöglichen gleichzeitig sowohl eine detaillierte Untersuchung auf Zeilenebene als auch aggregierte Ansichten auf hoher Ebene für tiefere Einblicke. Die Einbettung einer Drag-and-Drop-Schnittstelle im Tableau-Stil direkt in das Pocket book ermöglicht schnelle Hypothesentests, intuitive Kohortenvergleiche und eine effiziente Datenqualitätsprüfung, und das alles ohne die Reibung, die durch den Wechsel zwischen Code- und Visualisierungstools entsteht.
import sys, subprocess, json, math, os
from pathlib import Path
def pip_install(pkgs):
subprocess.check_call((sys.executable, "-m", "pip", "set up", "-q") + pkgs)
pip_install((
"pygwalker>=0.4.9",
"duckdb>=0.10.0",
"pandas>=2.0.0",
"numpy>=1.24.0",
"seaborn>=0.13.0"
))
import numpy as np
import pandas as pd
import seaborn as sns
df_raw = sns.load_dataset("titanic").copy()
print("Uncooked form:", df_raw.form)
show(df_raw.head(3))
Wir richten eine saubere und reproduzierbare Colab-Umgebung ein, indem wir alle erforderlichen Abhängigkeiten für interaktives EDA installieren. Wir laden den Titanic-Datensatz und führen eine erste Plausibilitätsprüfung durch, um seine Rohstruktur und seinen Umfang zu verstehen. Es schafft eine stabile Grundlage, bevor eine Transformation oder Visualisierung beginnt.
def make_safe_bucket(collection, bins=None, labels=None, q=None, prefix="bucket"):
s = pd.to_numeric(collection, errors="coerce")
if q will not be None:
attempt:
cuts = pd.qcut(s, q=q, duplicates="drop")
return cuts.astype("string").fillna("Unknown")
besides Exception:
cross
if bins will not be None:
cuts = pd.reduce(s, bins=bins, labels=labels, include_lowest=True)
return cuts.astype("string").fillna("Unknown")
return s.astype("float64")
def preprocess_titanic_advanced(df):
out = df.copy()
out.columns = (c.strip().decrease().change(" ", "_") for c in out.columns)
for c in ("survived", "pclass", "sibsp", "parch"):
if c in out.columns:
out(c) = pd.to_numeric(out(c), errors="coerce").fillna(-1).astype("int64")
if "age" in out.columns:
out("age") = pd.to_numeric(out("age"), errors="coerce").astype("float64")
out("age_is_missing") = out("age").isna()
out("age_bucket") = make_safe_bucket(
out("age"),
bins=(0, 12, 18, 30, 45, 60, 120),
labels=("little one", "teen", "young_adult", "grownup", "mid_age", "senior"),
)
if "fare" in out.columns:
out("fare") = pd.to_numeric(out("fare"), errors="coerce").astype("float64")
out("fare_is_missing") = out("fare").isna()
out("log_fare") = np.log1p(out("fare").fillna(0))
out("fare_bucket") = make_safe_bucket(out("fare"), q=8)
for c in ("intercourse", "class", "who", "embarked", "alone", "adult_male"):
if c in out.columns:
out(c) = out(c).astype("string").fillna("Unknown")
if "cabin" in out.columns:
out("deck") = out("cabin").astype("string").str.strip().str(0).fillna("Unknown")
out("deck_is_missing") = out("cabin").isna()
else:
out("deck") = "Unknown"
out("deck_is_missing") = True
if "ticket" in out.columns:
t = out("ticket").astype("string")
out("ticket_len") = t.str.len().fillna(0).astype("int64")
out("ticket_has_alpha") = t.str.accommodates(r"(A-Za-z)", regex=True, na=False)
out("ticket_prefix") = t.str.extract(r"^((A-Za-z./s)+)", broaden=False).fillna("None").str.strip()
out("ticket_prefix") = out("ticket_prefix").change("", "None").astype("string")
if "sibsp" in out.columns and "parch" in out.columns:
out("family_size") = (out("sibsp") + out("parch") + 1).astype("int64")
out("is_alone") = (out("family_size") == 1)
if "title" in out.columns:
title = out("title").astype("string").str.extract(r",s*((^.)+).", broaden=False).fillna("Unknown").str.strip()
vc = title.value_counts(dropna=False)
preserve = set(vc(vc >= 15).index.tolist())
out("title") = title.the place(title.isin(preserve), different="Uncommon").astype("string")
else:
out("title") = "Unknown"
out("phase") = (
out("intercourse").fillna("Unknown").astype("string")
+ " | "
+ out("class").fillna("Unknown").astype("string")
+ " | "
+ out("age_bucket").fillna("Unknown").astype("string")
)
for c in out.columns:
if out(c).dtype == bool:
out(c) = out(c).astype("int64")
if out(c).dtype == "object":
out(c) = out(c).astype("string")
return out
df = preprocess_titanic_advanced(df_raw)
print("Prepped form:", df.form)
show(df.head(3))
Wir konzentrieren uns auf fortschrittliche Vorverarbeitung und Characteristic-Engineering, um die Rohdaten in eine analysebereite Kind umzuwandeln. Wir erstellen robuste, DuckDB-sichere Funktionen wie Buckets, Segmente und konstruierte kategoriale Signale, die die nachgelagerte Exploration verbessern. Wir stellen sicher, dass der Datensatz stabil, ausdrucksstark und für interaktive Abfragen geeignet ist.
def data_quality_report(df):
rows = ()
n = len(df)
for c in df.columns:
s = df(c)
miss = int(s.isna().sum())
miss_pct = (miss / n * 100.0) if n else 0.0
nunique = int(s.nunique(dropna=True))
dtype = str(s.dtype)
pattern = s.dropna().head(3).tolist()
rows.append({
"col": c,
"dtype": dtype,
"lacking": miss,
"missing_%": spherical(miss_pct, 2),
"nunique": nunique,
"sample_values": pattern
})
return pd.DataFrame(rows).sort_values(("lacking", "nunique"), ascending=(False, False))
dq = data_quality_report(df)
show(dq.head(20))
RANDOM_SEED = 42
MAX_ROWS_FOR_UI = 200_000
df_for_ui = df
if len(df_for_ui) > MAX_ROWS_FOR_UI:
df_for_ui = df_for_ui.pattern(MAX_ROWS_FOR_UI, random_state=RANDOM_SEED).reset_index(drop=True)
agg = (
df.groupby(("phase", "deck", "embarked"), dropna=False)
.agg(
n=("survived", "measurement"),
survival_rate=("survived", "imply"),
avg_fare=("fare", "imply"),
avg_age=("age", "imply"),
)
.reset_index()
)
for c in ("survival_rate", "avg_fare", "avg_age"):
agg(c) = agg(c).astype("float64")
Path("/content material").mkdir(mother and father=True, exist_ok=True)
df_for_ui.to_csv("/content material/titanic_prepped_for_ui.csv", index=False)
agg.to_csv("/content material/titanic_agg_segment_deck_embarked.csv", index=False)
Wir bewerten die Datenqualität und erstellen einen strukturierten Überblick über Fehlen, Kardinalität und Datentypen. Wir bereiten sowohl einen Datensatz auf Zeilenebene als auch eine aggregierte Tabelle auf Kohortenebene vor, um eine schnelle Vergleichsanalyse zu unterstützen. Die duale Darstellung ermöglicht es uns, gleichzeitig detaillierte Muster und übergeordnete Traits zu untersuchen.
import pygwalker as pyg
SPEC_PATH = Path("/content material/pygwalker_spec_titanic.json")
def load_spec(path):
if path.exists():
attempt:
return json.hundreds(path.read_text())
besides Exception:
return None
return None
def save_spec(path, spec_obj):
attempt:
if isinstance(spec_obj, str):
spec_obj = json.hundreds(spec_obj)
path.write_text(json.dumps(spec_obj, indent=2))
return True
besides Exception:
return False
def launch_pygwalker(df, spec_path):
spec = load_spec(spec_path)
kwargs = {}
if spec will not be None:
kwargs("spec") = spec
attempt:
walker = pyg.stroll(df, use_kernel_calc=True, **kwargs)
besides TypeError:
walker = pyg.stroll(df, **kwargs) if spec will not be None else pyg.stroll(df)
captured = None
for attr in ("spec", "_spec"):
if hasattr(walker, attr):
attempt:
captured = getattr(walker, attr)
break
besides Exception:
cross
for meth in ("to_spec", "export_spec", "get_spec"):
if captured is None and hasattr(walker, meth):
attempt:
captured = getattr(walker, meth)()
break
besides Exception:
cross
if captured will not be None:
save_spec(spec_path, captured)
return walker
walker_rows = launch_pygwalker(df_for_ui, SPEC_PATH)
walker_agg = pyg.stroll(agg)
Wir integrieren PyGWalker, um unsere vorbereiteten Tabellen in eine vollständig interaktive Drag-and-Drop-Analyseschnittstelle umzuwandeln. Wir behalten die Visualisierungsspezifikation bei, sodass Dashboard-Layouts und Codierungen auch Pocket book-Wiederholungen überdauern. Es verwandelt das Pocket book in eine wiederverwendbare Erkundungsumgebung im BI-Stil.
HTML_PATH = Path("/content material/pygwalker_titanic_dashboard.html")
def export_html_best_effort(df, spec_path, out_path):
spec = load_spec(spec_path)
html = None
attempt:
html = pyg.stroll(df, spec=spec, return_html=True) if spec will not be None else pyg.stroll(df, return_html=True)
besides Exception:
html = None
if html is None:
for fn in ("to_html", "export_html"):
if hasattr(pyg, fn):
attempt:
f = getattr(pyg, fn)
html = f(df, spec=spec) if spec will not be None else f(df)
break
besides Exception:
proceed
if html is None:
return None
if not isinstance(html, str):
html = str(html)
out_path.write_text(html, encoding="utf-8")
return out_path
export_html_best_effort(df_for_ui, SPEC_PATH, HTML_PATH)
Wir erweitern den Workflow, indem wir das interaktive Dashboard als eigenständiges HTML-Artefakt exportieren. Wir stellen sicher, dass die Analyse geteilt oder überprüft werden kann, ohne dass eine Python-Umgebung oder eine Colab-Sitzung erforderlich ist. Es vervollständigt die Pipeline von Rohdaten bis hin zu verteilbaren, interaktiven Erkenntnissen.


Zusammenfassend haben wir ein robustes Muster für fortgeschrittene EDA erstellt, das weit über den Titanic-Datensatz hinaus skaliert und gleichzeitig vollständig Pocket book-nativ bleibt. Wir haben gezeigt, wie sorgfältige Vorverarbeitung, Typsicherheit und Characteristic-Design es PyGWalker ermöglichen, zuverlässig mit komplexen Daten zu arbeiten, und wie die Kombination detaillierter Datensätze mit aggregierten Zusammenfassungen leistungsstarke analytische Arbeitsabläufe ermöglicht. Anstatt die Visualisierung als nachträglichen Gedanken zu behandeln, nutzten wir sie als erstklassige interaktive Ebene, die es uns ermöglichte, Annahmen zu iterieren, zu validieren und Erkenntnisse in Echtzeit zu gewinnen.
Schauen Sie sich das an Vollständige Codes hier. Sie können uns auch gerne weiter folgen Twitter und vergessen Sie nicht, bei uns mitzumachen 100.000+ ML SubReddit und Abonnieren Unser Publication. Warten! Bist du im Telegram? Jetzt können Sie uns auch per Telegram kontaktieren.

