pandas: leeres Dataframe mit einer Schleif e füllen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

Hallo Leute!
folgendes Beispiel:

Code: Alles auswählen

#erstelle nur mal ein Beispiel wie so ein DataFrame aussehen könnte
test = [{'A':10, 'B':100}, {'A':11,'B':110}, {'A':12,'B':120}]
df1 = pd.DataFrame(test)
#dann erstelle ich ein leeres Dataframe, die spalten sind ja sogar bekannt 
df2 = pd.DataFrame(columns=['c1', 'c2'])
#und nun möchte ich es mit einer For-Schleife wieder füllen
for index, row in df1.iterrows():
    df2.append(row, ignore_index=True)
Eigentlich sollte nun df1 == df2 sein. df2 ist aber immer noch leer.
Für meine Aufgabe muss ich nämlich für jede Zeile in der For-Schleife etwas berechnen und anschließend entscheiden ob ich sie behalten möchte.
Ich finde auch in anderen Foren nicht die gewünschte Lösung die sich dann auch anwenden lässt.
Das Ganze in ein numpy-array umwandeln, bearbeiten und wieder in ein Dataframe zurückwandern funktioniert auch nicht da mir die Spalten Namen verloren gehen.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Julien456935: `DataFrame.append()` verändert nicht den `DataFrame` sondern erstellt einen neuen und gibt den zurück. Weshalb das in der Schleife auch sehr ineffizient ist. Du gehst das falsch an. Da Du nicht sagst was Du genau machen möchtest ist es jetzt auch nicht so einfach eine der zig Möglichkeiten zu empfehlen Zeilen auszuwählen ohne eine lahme Python-Schleife zu schreiben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

so würde es gehen, aber wie gesagt, sehr ineffizient

Code: Alles auswählen

for index, row in df1.iterrows():
    df2 = df2.append(row, ignore_index=True)
Im übrigen hilft eine einfaches
help(pd.DataFrame.append) und man bekommt die Doku
append(self, other, ignore_index=False, verify_integrity=False, sort=None)
Append rows of `other` to the end of caller, returning a new object.
Columns in `other` that are not in the caller are added as new columns.
.....
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

@ThomasL & @__blackjack__: Also der Codestück @ThomasL funktioniert bin dann aber auch gleich draufgekommen, dass es mir nicht weiterhilft.
Das Problem ist ich habe einen riesigen Datensatz:
--> Geräte_id, Breitengrad, Längengrad, Meßzeit, usw... (Datensatz)
--> Zusätzlich habe ich eine Liste von Werten

Ich muss also eine Zeile einlesen aus dem Längengrad und Breitengrad einen Wert berechnen und den berechneten Wert mit jedem Wert aus meiner Liste vergleichen. Ohne in zwei ineinander geschachtelte FOR Schleifen wird das ebben glaube ich nicht funktionieren und das dauert ebben ewig.
Fakt ist ich muss Jede Zeile aufrufen und den Wert berechnen, sonst kann ich gar nicht sagen ob diese Zeile für mich Relevant ist. Das erfordert mindestens eine For-schleife und der "Vergleich" wird eine weiter For Schleife benötigen.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Julien456935: Also ich sehe das so wirklich zwingend noch gar keine Schleife die *Du* schreiben müsstest wenn Du den Wert mit den `Series`-Objekten ausrechnen und für den Test die `isin()`-Methode verwenden kannst.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

@Julien ich kann deinen Ausführungen nicht ganz folgen, verstehe also nicht was du eigentlich machen willst.
Gib uns doch mal einen abgespeckten Datensatz df1 mit ca. 20 Einträgen und eine dazu passende Liste und
beschreibe Schritt für Schritt was du machen willst/musst und wie dann das Endergebnis aussehen soll.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

So habe jetzt mal ein ausführliches Example mit Beschreibung hingeschrieben:

Code: Alles auswählen

# =============================================================================
# Example
# =============================================================================


#example Data:
import pandas as pd

example_data = [{"id" : 325, "lat" : 52, "lon" : 14, "weitere Werte" : "XY"},
                {"id" : 151, "lat" : 48, "lon" : 9, "weitere Werte" : "XY"},
                {"id" : 197, "lat" : 45, "lon" : 11, "weitere Werte" : "XY"},
                {"id" : 456, "lat" : 30, "lon" : 17, "weitere Werte" : "XY"},
                {"id" : 325, "lat" : 52, "lon" : 14, "weitere Werte" : "XY"},
                {"id" : 325, "lat" : 52, "lon" : 14, "weitere Werte" : "XY"},
                {"id" : 151, "lat" : 48, "lon" : 9, "weitere Werte" : "XY"},
                {"id" : 325, "lat" : 52, "lon" : 14, "weitere Werte" : "XY"},
                {"id" : 197, "lat" : 45, "lon" : 11, "weitere Werte" : "XY"},
                {"id" : 456, "lat" : 30, "lon" : 17, "weitere Werte" : "XY"},
                {"id" : 325, "lat" : 52, "lon" : 14, "weitere Werte" : "XY"},
                {"id" : 477, "lat" : 34, "lon" : 21, "weitere Werte" : "XY"}]

df1 = pd.DataFrame(example_data)

#df1
#Out[184]: 
#     id  lat  lon weitere Werte
#0   325   52   14            XY
#1   151   48    9            XY
#2   197   45   11            XY
#3   456   30   17            XY
#4   325   52   14            XY
#5   325   52   14            XY
#6   151   48    9            XY
#7   325   52   14            XY
#8   197   45   11            XY
#9   456   30   17            XY
#10  325   52   14            XY
#11  477   34   21            XY


#Example List: ist in wirklichkeit eine Liste von objekten, aber sollte als Beispiel
#keine Rolle spielen

example_list = [10, 30, 50, 70, 90]

#ich muss nun einen Wert Jeder Zeile Berechnen sagen wir mal ganz simple lat + lon
#zb erste Zeile 52 + 14 = 66
#Diesen Wert (66) möchte ich nun mit allen zahlen in der Liste Vergleichen und 
#falls er größer ist benötige ich ihn
#im ersten fall ist 66 größer als jeder dieser Werte trifft also auf alle zu
#damit ich den datensatz schnell komprimmieren kann würde ich auch die isin()`-Methode
#verwenden und würde deshalb ein Dictionary erstellen und zu jeder Zahl in der Liste die Sensor_id
#hinzufügen
#für die Erste Zeile wäre also der Dictionary Eintrag wie folgt.

#dic = {10 : [325], 20 : [325], 30 : [325], 40 : [325], 50 : [325]}
#dic
#Out[186]: {10: [325], 20: [325], 30: [325], 40: [325], 50: [325]}

#im laufe der Itteration über die Zeilen werden die listen gefühlt.

dic = {}
help_list = []
for number in example_list:
    for index, row in df1.iterrows():
        if number < (row["lat"] + row["lon"]):
            help_list.append(row["id"])
    dic[number] = help_list
    help_list = []
    
#dic
#Out[222]: 
#{10: [325, 151, 197, 456, 325, 325, 151, 325, 197, 456, 325, 477],
# 30: [325, 151, 197, 456, 325, 325, 151, 325, 197, 456, 325, 477],
# 50: [325, 151, 197, 325, 325, 151, 325, 197, 325, 477],
# 70: [],
# 90: []}
    
#Nun da es statt 10,30,50,70,90 eine lange liste von obkekten ist und auch der id-Datensatz eine
#csv von 1Gb ist selbst mit einer kleinen Test csv von nur 20 Mb sind Tasusende von Zeilen enthalten
#und die laufzeit viel zu lange... 
    
#die isin()Methode würde ich dann anschließend anwenden, denn wenn ich mal eine Liste der ids zum 
#jeweilige Objekt habe sollte der Datensatz ziemlich schnell komprimierbar sein... trotzdem sehe ich noch
#keine Möglichkeit nicht alle Zeilen einzulesen. 
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Was würdest Du zu diesem Code sagen?

Code: Alles auswählen

lat_lon = df1['lat'] + df1['lon']
for number in example_list:
    print(number)
    print(df1[number < lat_lon])
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Julien456935 hat geschrieben: Samstag 20. April 2019, 23:46

Code: Alles auswählen

example_list = [10, 30, 50, 70, 90]
# ich muss nun einen Wert Jeder Zeile Berechnen sagen wir mal ganz simple lat + lon   zb erste Zeile 52 + 14 = 66
# Diesen Wert (66) möchte ich nun mit allen zahlen in der Liste Vergleichen und falls er größer ist benötige ich ihn
[b]# im ersten fall ist 66 größer als jeder dieser Werte trifft also auf alle zu[/b]
Diese Beschreibung ist widersprüchlich, 66 ist NICHT größer als jeder Wert in der example_list
Des Weiteren, WAS benötigst du dann, nur den Wert 66 oder die Reihe aus der du 66 gebastelt hast etc.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Julien456935
User
Beiträge: 19
Registriert: Donnerstag 22. November 2018, 15:26

@ThomasL: Stimmst diese Zeile ist Widersprüchlich ich habe, zum Schluss die Werte der Liste nochmal geändert damit das Beispiel sinnvoller erscheint und habe diesen Satz vergessen.
@__blackjack__: Danke das war ein sehr interessanter Ansatz. Habe ein Vergleichs-Data_Frame erstellt und alles ging super schnell. Habe allerdings nicht eine einfache Addition, sondern eine sehr komplizierte Rechnung dahinter. Ich habe bei meinem Beispiel nun so lange herumgespielt bis ich nach 2 Tagen endlich draufgekommen bin das es durch eine selbstgeschrieben Funktion 3 in einander gekästelte For-Schleifen waren :oops: ... Ich konnte durch komplettes umstrukturieren die Laufzeit nun auf 2 Minuten heruntersetzen und damit kann ich leben. Werd in Zukunft einfach mehr darauf Acht geben müssen :D
Antworten