Auswahl in einer gefilterten Tabelle treffen
Um die ausgewählten Zeilen aus einem st.dataframe (oder st.data_editor) in Streamlit abzurufen, nutzt du am besten das Argument on_select="rerun" zusammen mit der selection_mode-Option.
Seit den neueren Streamlit-Versionen ist dies der eleganteste Weg, da die Auswahl direkt ein interaktives Objekt zurückgibt, das auch mit Filtern perfekt funktioniert.
Hier ist ein einfaches, direkt einsatzbereites Code-Beispiel:
import streamlit as st
import pandas as pd
#1. Beispiel-Daten erstellen
data = {
„Name“: [„Anna“, „Ben“, „Charlie“, „Diana“],
„Alter“: [23, 35, 41, 29],
„Stadt“: [„Berlin“, „Hamburg“, „München“, „Köln“]
}
df = pd.DataFrame(data)
st.title(„Gefilterte Tabelle & Zeilenauswahl“)
#2. Filter einbauen (z. B. nach Stadt)
staedte = st.multiselect(„Filter nach Stadt“, options=df[„Stadt“].unique(), default=df[„Stadt“].unique())
filtered_df = df[df[„Stadt“].isin(staedte)]
#3. Dataframe mit Auswahlfunktion anzeigen
#Wichtig: on_select=“rerun“ aktiviert das Event-Handling
event = st.dataframe(
filtered_df,
use_container_width=True,
on_select=“rerun“,
selection_mode=“single_row“ # Oder „multi_row“ für mehrere Zeilen
)
#4. Ausgewählte Zeile abfragen
#Das ‚event‘-Objekt enthält die Indizes unter .selection.rows
selected_rows_indices = event.selection.rows
if selected_rows_indices:
# Da wir die gefilterte Tabelle übergeben haben, müssen wir .iloc nutzen,
# um die Zeile basierend auf der aktuellen Tabellenansicht zu greifen
selected_data = filtered_df.iloc[selected_rows_indices]
st.write("### Ausgewählte Zeile(n):")
st.dataframe(selected_data)
else:
st.info("Klicke auf das linke Kästchen einer Zeile, um sie auszuwählen.")
Warum das auch beim Filtern klappt (Der iloc-Klick)
Das Geheimnis bei gefilterten Tabellen liegt in der Verwendung von .iloc[] statt .loc[]:
event.selection.rowsgibt dir immer den visuellen Index der Zeile zurück, die der User gerade sieht (also0für die erste sichtbare Zeile,1für die zweite usw.).- Wenn du den Filter änderst, schrumpft deine Tabelle
filtered_df. Die erste Zeile darin hat für Streamlit wieder den visuellen Index0. - Mit
filtered_df.iloc[selected_rows_indices]greifst du exakt diesen visuellen Zustand ab, unabhängig davon, welchen Index die Zeile ursprünglich im großen Datensatz hatte.
Tipps für die Praxis:
- Mehrfachauswahl: Wenn du
selection_mode="multi_row"nutzt, liefert direvent.selection.rowseine Liste aller markierten Zeilen (z. B.[0, 2]).ilockommt damit problemlos klar und gibt dir alle ausgewählten Zeilen zurück. - Spaltenauswahl: Falls du eher an bestimmten Spalten interessiert bist, kannst du auch
selection_mode="single_column"oder"multi_column"nutzen und die Auswahl viaevent.selection.columnsabgreifen.