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.rows gibt dir immer den visuellen Index der Zeile zurück, die der User gerade sieht (also 0 für die erste sichtbare Zeile, 1 fü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 Index 0.
  • 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 dir event.selection.rows eine Liste aller markierten Zeilen (z. B. [0, 2]). iloc kommt 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 via event.selection.columns abgreifen.