2024-10-03 11:40:50 +02:00
import streamlit as st
import pandas as pd
import numpy as np
import plotly . express as px
2024-10-03 11:45:57 +02:00
st . title ( " Erweiterter List Data Visualizer & Analyzer " )
2024-10-03 11:40:50 +02:00
# Seitenleiste für die Dateneingabe
st . sidebar . header ( " Dateneingabe " )
datenquelle = st . sidebar . radio ( " Datenquelle auswählen: " , ( " Manuelle Eingabe " , " CSV-Datei hochladen " ) )
if datenquelle == " Manuelle Eingabe " :
2024-10-03 11:45:57 +02:00
dateneingabe = st . sidebar . text_area ( " Gib Zahlen ein, getrennt durch Kommas oder Zeilenumbrüche: " , value = " 1,2,3,4,5 " )
2024-10-03 11:40:50 +02:00
try :
2024-10-03 11:45:57 +02:00
daten_zeilen = [ zeile . strip ( ) for zeile in dateneingabe . strip ( ) . split ( " \n " ) if zeile . strip ( ) ]
2024-10-03 11:49:21 +02:00
if len ( daten_zeilen ) == 1 :
# Eindimensionale Daten (eine Zeile ohne Zeilenumbrüche)
datenliste = [ float ( x . strip ( ) ) for x in daten_zeilen [ 0 ] . split ( " , " ) if x . strip ( ) ]
df = pd . DataFrame ( datenliste , columns = [ ' Werte ' ] )
else :
# Mehrdimensionale Daten (mehrere Zeilen)
datenliste = [ list ( map ( float , zeile . split ( ' , ' ) ) ) for zeile in daten_zeilen ]
df = pd . DataFrame ( datenliste )
df . columns = [ f " Spalte { i + 1 } " for i in range ( df . shape [ 1 ] ) ]
2024-10-03 11:40:50 +02:00
except ValueError :
st . error ( " Bitte gib eine gültige Liste von Zahlen ein. " )
st . stop ( )
elif datenquelle == " CSV-Datei hochladen " :
hochgeladene_datei = st . sidebar . file_uploader ( " Wähle eine CSV-Datei aus " , type = " csv " )
if hochgeladene_datei is not None :
df = pd . read_csv ( hochgeladene_datei )
2024-10-03 11:45:57 +02:00
# Numerische Spalten identifizieren
numerische_spalten = df . select_dtypes ( include = [ np . number ] ) . columns . tolist ( )
if not numerische_spalten :
st . error ( " Die hochgeladene Datei enthält keine numerischen Spalten. " )
st . stop ( )
st . sidebar . subheader ( " Spaltenauswahl " )
ausgewählte_spalten = st . sidebar . multiselect ( " Wähle die Spalten für die Analyse aus " , numerische_spalten , default = numerische_spalten )
if not ausgewählte_spalten :
st . error ( " Bitte wähle mindestens eine Spalte aus. " )
st . stop ( )
df = df [ ausgewählte_spalten ]
2024-10-03 11:40:50 +02:00
else :
st . warning ( " Bitte lade eine CSV-Datei hoch. " )
st . stop ( )
2024-10-03 11:45:57 +02:00
else :
st . error ( " Ungültige Datenquelle ausgewählt. " )
st . stop ( )
2024-10-03 11:40:50 +02:00
# Interaktive Filter
st . sidebar . header ( " Datenfilter " )
2024-10-03 11:45:57 +02:00
gefilterter_df = df . copy ( )
for spalte in df . columns :
# Konvertiere die Spalte in numerische Werte und entferne NaN
gefilterter_df [ spalte ] = pd . to_numeric ( gefilterter_df [ spalte ] , errors = ' coerce ' )
gefilterter_df = gefilterter_df . dropna ( subset = [ spalte ] )
min_wert = float ( gefilterter_df [ spalte ] . min ( ) )
max_wert = float ( gefilterter_df [ spalte ] . max ( ) )
# Überprüfen, ob min_wert und max_wert unterschiedlich sind
if min_wert == max_wert :
st . warning ( f " Die Spalte ' { spalte } ' hat konstante Werte. Der Slider wird für diese Spalte deaktiviert. " )
continue # Überspringe diese Spalte
# Slider erstellen
filterbereich = st . sidebar . slider (
f " Wertebereich für ' { spalte } ' auswählen: " ,
min_value = min_wert ,
max_value = max_wert ,
value = ( min_wert , max_wert )
)
# Daten filtern
gefilterter_df = gefilterter_df [ ( gefilterter_df [ spalte ] > = filterbereich [ 0 ] ) & ( gefilterter_df [ spalte ] < = filterbereich [ 1 ] ) ]
2024-10-03 11:40:50 +02:00
# Statistische Analyse
st . header ( " Statistische Analyse " )
2024-10-03 11:45:57 +02:00
def berechne_statistiken ( daten ) :
beschreibung = daten . describe ( ) . transpose ( )
beschreibung [ ' Median ' ] = daten . median ( )
beschreibung [ ' Varianz ' ] = daten . var ( )
return beschreibung [ [ ' count ' , ' mean ' , ' Median ' , ' std ' , ' Varianz ' , ' min ' , ' 25 % ' , ' 50 % ' , ' 75 % ' , ' max ' ] ]
2024-10-03 11:40:50 +02:00
2024-10-03 11:45:57 +02:00
statistiken = berechne_statistiken ( gefilterter_df )
st . dataframe ( statistiken )
2024-10-03 11:40:50 +02:00
2024-10-03 11:45:57 +02:00
# Ausreißererkennung
st . header ( " Ausreißererkennung " )
ausreisser_df = pd . DataFrame ( )
2024-10-03 11:40:50 +02:00
2024-10-03 11:45:57 +02:00
for spalte in gefilterter_df . columns :
Q1 = gefilterter_df [ spalte ] . quantile ( 0.25 )
Q3 = gefilterter_df [ spalte ] . quantile ( 0.75 )
IQR = Q3 - Q1
untere_grenze = Q1 - 1.5 * IQR
obere_grenze = Q3 + 1.5 * IQR
ausreisser = gefilterter_df [ ( gefilterter_df [ spalte ] < untere_grenze ) | ( gefilterter_df [ spalte ] > obere_grenze ) ]
ausreisser_df = pd . concat ( [ ausreisser_df , ausreisser ] )
if not ausreisser_df . empty :
2024-10-03 11:40:50 +02:00
st . subheader ( " Erkannte Ausreißer " )
2024-10-03 11:45:57 +02:00
st . write ( ausreisser_df . drop_duplicates ( ) )
2024-10-03 11:40:50 +02:00
else :
st . subheader ( " Keine Ausreißer erkannt " )
2024-10-03 11:45:57 +02:00
# Visualisierungen
st . header ( " Datenvisualisierungen " )
st . sidebar . header ( " Visualisierungseinstellungen " )
diagramm_typ = st . sidebar . selectbox ( " Diagrammtyp auswählen " , [ " Histogramm " , " Boxplot " , " Streudiagramm " , " Liniendiagramm " , " Korrelationsmatrix " ] )
if diagramm_typ == " Histogramm " :
st . subheader ( " Histogramm " )
ausgewählte_spalten = st . multiselect ( " Wähle die Spalten für das Histogramm aus " , gefilterter_df . columns . tolist ( ) , default = gefilterter_df . columns . tolist ( ) )
for spalte in ausgewählte_spalten :
fig = px . histogram ( gefilterter_df , x = spalte , nbins = 20 , title = f ' Histogramm von { spalte } ' )
st . plotly_chart ( fig )
elif diagramm_typ == " Boxplot " :
st . subheader ( " Boxplot " )
fig = px . box ( gefilterter_df , points = " all " , title = ' Boxplot ' )
st . plotly_chart ( fig )
elif diagramm_typ == " Streudiagramm " :
if len ( gefilterter_df . columns ) > = 2 :
x_achse = st . sidebar . selectbox ( " X-Achse " , gefilterter_df . columns )
y_achse = st . sidebar . selectbox ( " Y-Achse " , gefilterter_df . columns , index = 1 )
st . subheader ( " Streudiagramm " )
fig = px . scatter ( gefilterter_df , x = x_achse , y = y_achse , title = f ' Streudiagramm { x_achse } vs { y_achse } ' )
st . plotly_chart ( fig )
else :
st . warning ( " Für ein Streudiagramm sind mindestens zwei numerische Spalten erforderlich. " )
elif diagramm_typ == " Liniendiagramm " :
st . subheader ( " Liniendiagramm " )
ausgewählte_spalten = st . multiselect ( " Wähle die Spalten für das Liniendiagramm aus " , gefilterter_df . columns . tolist ( ) , default = gefilterter_df . columns . tolist ( ) )
fig = px . line ( gefilterter_df , y = ausgewählte_spalten , title = ' Liniendiagramm ' )
st . plotly_chart ( fig )
elif diagramm_typ == " Korrelationsmatrix " :
if len ( gefilterter_df . columns ) > = 2 :
st . subheader ( " Korrelationsmatrix " )
korrelation = gefilterter_df . corr ( )
fig = px . imshow ( korrelation , text_auto = True , title = ' Korrelationsmatrix ' )
st . plotly_chart ( fig )
else :
st . warning ( " Für eine Korrelationsmatrix sind mindestens zwei numerische Spalten erforderlich. " )
2024-10-03 11:40:50 +02:00
# Gefilterte Daten anzeigen
st . header ( " Gefilterte Daten " )
st . write ( gefilterter_df )