Seite 1 von 1

pandas Dataframes - Problematik mit .append()

Verfasst: Mittwoch 19. Mai 2021, 20:45
von CSchilling
Guten Abend,

ich steh wieder einmal vor einer kleinen Umsetzungsproblematik....

ich lade mit pandas aus einer .csv-file Daten ein und möchte diesem Dataframe dann nach und nach neue Daten am Ende hinzufügen.
Der folgende Code-Snippet stellt nur den Code Baustein aus meinem eigentlich Programm nach und soll verdeutlichen wo mein Problem liegt.

Code: Alles auswählen

df = pd.read_csv(path2)
if df.shape[0] < max(28, 48, 14, 21):
    df_add = pd.read_csv(path1)
    df = df_add.append(df, ignore_index=True)
Muss ich nun, wenn ich neue Werte zum Dataframe hinzufüge wie bei unterhalb stehendem Code dies jedes mal in einer Variablen speichern?

Code: Alles auswählen

df = df_add.append(df, ignore_index=True)
Wenn ich nun an einer späteren Stelle im Programm die Function .append auf "df" anwende(siehe Code unterhalb) und dann danach die variable "df" mir ausgeben lasse, wurden die werte nicht hinzugefügt.

Code: Alles auswählen

df.append({'RSI': 100, 'EMA_UP': 50}, ignore_index=True)
print(df)

Vielen Dank wiedermal für Ideen und Anregungen.

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Mittwoch 19. Mai 2021, 21:13
von __blackjack__
@CSchilling: `append()` fügt nicht zu dem `DateFrame` hinzu, sondern erstellt einen neuen in den die alten Daten kopiert werden und am Ende die neuen hinzugefügt werden. Ist also nicht besonders effizient.

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Mittwoch 19. Mai 2021, 21:41
von CSchilling
__blackjack__ hat geschrieben: Mittwoch 19. Mai 2021, 21:13 @CSchilling: `append()` fügt nicht zu dem `DateFrame` hinzu, sondern erstellt einen neuen in den die alten Daten kopiert werden und am Ende die neuen hinzugefügt werden. Ist also nicht besonders effizient.
ah alles klar. Dann macht das Sinn.
Gibt es denn eine effizientere Lösung dafür?
Bisher habe ich immer über eine "einfache" "with open(....) as file:" die Dateien in eine Liste eingelesen und dann im Programm die neu errechneten Werte an diese Liste angehängt.
Jedoch kam es gelegentlich zu Problemen, wenn mein Programm aufgrund eines Verbindungsverlusts zum Websocket-Server neugestartet hat. Das Problem lag daran, dass ich jedesmal wenn das Programm neustartet, die Daten aus einer csv Datei neu einlesen lasse.
Diese Daten stehen Tagsüber in einer Datei. Jedoch immer um 0:00 wird eine neue Datei erstellt. Wenn nun das Programm kurz nach 0:00 Uhr neustartet, dann sind in der kürzlich erstellen csv. Datei nicht ausreichend Daten vorhanden, deswegen müssen die restlichen Daten aus der csv. des vortages gelesen werden. Das funktioniert einfach und schnell mit pandas funktion ".append()".


Mein Programm bekommt im weitern Verlauf alle 250ms Daten von einem Websocket-Server. Alle 5 Minuten wirdaus diesen Daten ein Indikator berrechnet, welcher dann ans Ende einer Liste oder eben dem DataFrame angehängt werden soll um später im Programm damit zu arbeiten.
Das Programm hängt halt quasi in der on_message() funktion fest, solange der Websocket-Server Daten sendet.

Unterhalb habe ich einen Teil des Codes eingefügt, welcher sich mit dem "Problem" beschäftigt.

Code: Alles auswählen


.....



df = pd.read_csv(path_storage('Historical-Data', 0, symbol, interval))
if df.shape[0] < max(period_l_t, period_l_a, period_u_a, period_u_t):
    df_add = pd.read_csv(path_storage('Historical-Data', 1, symbol, interval))
    df = df_add.append(df, ignore_index=True)


def on_message(wsapp, message):
	#   Receiving data from websocket request message (every ~~250ms).
    stream_data = json.loads(message)  # raw Data send back from websocket for the recent active candle.

    #   Process the data from the websocket stream.
    if stream_data['k']['x']:  # the send datapackage does contain the candle closing data.
        rsi_5m = shortterm_rsi(float(stream_data['k']['c']),
                               df['CLOSES'].iloc[-1],
                               period_length_5m_rsi,
                               df['EMA_UP'].iloc[-1],
                               df['EMA_DOWN'].iloc[-1])
        df = df.append({'DATE': datetime.fromtimestamp(int(((stream_data['k']['t']) * 0.001))),
                        'OPEN': stream_data['k']['o'],
                        'HIGH': stream_data['k']['h'],
                        'LOW': stream_data['k']['l'],
                        'CLOSES': float(stream_data['k']['c']),
                        'EMA_UP': rsi_5m[1],
                        'EMA_DOWN': rsi_5m[2],
                        'RSI': rsi_5m[0]
                        }, ignore_index=True)
                        
        df = df.drop([0])

.....


Re: pandas Dataframes - Problematik mit .append()

Verfasst: Mittwoch 19. Mai 2021, 22:01
von __deets__
Für eine solche Anwendung benutzt man einfach eine Datenbank. Zb das schon mitgelieferte & rein datei-basierte sqlite. Das Skript das da reinschreibt, wird auch nicht unterbrochen oder beendet. Will man an die Daten ran, kann man das jederzeit parallel tun.

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Donnerstag 20. Mai 2021, 06:04
von ThomasL
Eventuell möchtest du auch concat anstelle von append benutzen.
https://pandas.pydata.org/docs/referenc ... das.concat

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Donnerstag 20. Mai 2021, 13:28
von CSchilling
Danke euch für die Anregungen!

SQLite3 macht wenn ich mich die letzten Stunden richtig informiert habe, in meinem Fall eingeschränkt Sinn, jedoch würde es an anderer Stelle wiederum für neuen Aufwand sorgen. Ich "sammele" die angefallenen Daten in .csv Dateien da ich diese mit anderen Softwareprogrammen weiterverarbeite oder teilweise auch and Drittpersonen verschicke. Und die Daten sollten jeweils - für den aktuellen Tag - in einer eigenen Datei gespeichert werden, sodass Drittpersonen diese .csv Dateien einfach verwenden können.

'concat' append macht doch genau das selbe wie append, erschafft ebenfalls eine neues DataFrame Object, was ich ja eigentlich vermeiden wollte.


Trotzdem danke für eure Hilfe.

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Donnerstag 20. Mai 2021, 13:32
von __deets__
Niemand hindert dich daran, aus den SQLlite Daten CSVs zu exportieren. Es löst nur lauter Probleme, die du im Moment hast. Sowohl in Bezug auf Effizienz (was eher ästhetisch ist, solange es funktioniert) als auch Fehlerfällen. Denn SQLite ist robust. Dateien öffnen, anhängen, Schreiben deutlich weniger.

Re: pandas Dataframes - Problematik mit .append()

Verfasst: Donnerstag 20. Mai 2021, 14:03
von CSchilling
__deets__ hat geschrieben: Donnerstag 20. Mai 2021, 13:32 Niemand hindert dich daran, aus den SQLlite Daten CSVs zu exportieren. Es löst nur lauter Probleme, die du im Moment hast. Sowohl in Bezug auf Effizienz (was eher ästhetisch ist, solange es funktioniert) als auch Fehlerfällen. Denn SQLite ist robust. Dateien öffnen, anhängen, Schreiben deutlich weniger.
Du hast auf jeden Fall recht, effizienter und sicherer ist es allemal. Ich bin nur noch zu unerfahren in Bezug auf Python, Programmieren und vor allem SQL und Datenbanken.
Mein eigentliches Problem ist auch nicht das laden und schreiben der Daten. Das oberhalb beschriebene Problem mit dem laden der Daten aus zwei files, entsteht nun sehr sehr selten. Ich wollte viel mehr pandas eigentliche funktionen des rolling().mean() und rolling().std() nutzen. Dann habe ich mir gedacht, damit könnte ich ja auch gleichzeitig das sehr selten auftretende Problem des importierens der Daten lösen.
Nur habe ich dann durch meinen noch sehr Laienhaften Code und das implementieren von pandas neue Störfaktoren erzeugt, welche ich im ersten Post versucht habe zu beschreiben.

Ich werde nun erstmal wieder mit den build-in statistics funktionen arbeiten und meine uneffiziente öffnen, anhängen, schreiben Methode wählen. Damit hat es bereits "gut" funktioniert.

Ich muss mir erstmal ein Verständnis zu Datenbanken und SQL anschaffen, damit ich das besser in meine Programme implementieren kann.


Danke auf jeden Fall für die Überzeugungsarbeite ;-)