Data.Frame mit Wert aus nested Dict zusammenfueren

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
BjoernLaemmerzahl
User
Beiträge: 22
Registriert: Sonntag 17. Mai 2015, 12:22

Hallo,

Als Python-Neuling bin ich leider am Ende meiner Ideen-Kiste angekommen. Mir will einfach nich einfallen, wie ich dieses Problem loesen kann. Im Prinzip versuche ich die Daten aus einem Data.Frame mit den Werten aus einem Dictionary zusammenzufuehren.

Ich habe zwei Objekte. Ein Dictionary mit einem nested Dictionary. Das sieht so aus:

Code: Alles auswählen

obj1 = {"A":
                         {"name":"A",
                          "production":
                             {"wind": 111, "solar": 222},
                          "consumption":
                              {"demand": 333}
                          },
                     "B":
                         {"name":"B",
                          "production":{"wind": 444, "solar": 555},
                          "consumption":
                              {"demand": 666}},
Mein zweites Objekt (obj2) ist ein Data.Frame mit folgender Struktur.

Code: Alles auswählen

	111	222 333 444 555 666 ...
1		5	6	7	8	9	
2		5	6	7	8	9
3		5	6	...
4		5	...
5		5
6		5
7		5
8		5
9		5
10		5
11		5

Fuer jeden Wert in dem "Unter-Dictionary" von obj1, "production" entsprich eine Spalte in dem Data.Frame in obj2.

Mein Ziel ist es, das die Spalten fuer jeden Wert addiert werden.

Das Ergebnis waere also folgender Data.Frame (obj3):

Code: Alles auswählen

	A	B
1	11	15
2	11	15
3	11	15
4	11	15
5	11	15
6	11	15
7	11	15
8	11	15
9	11	15
10	11	15

Hier meine bisheriger Loesungsversuch:

Code: Alles auswählen

obj3 = []

def MatchDictToFrame(d):
  global obj3
  for k, v in d.items():
    if isinstance(v, dict):
      print(v)
    else:
        obj3[obj1[k]["name"]] = obj2[dict_country_data[k].get("production")]

for k,v in obj1.items():
    (MatchDictToFrame(obj1["de"]["production"]))

Ich bin allerdings ziemlich sicher das meine Heransgehensweise komplett falsch ist. Leider bin ich kein Programmier....
Vielleicht kann mich ja einer in die richtige Richtung schupsen....
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@BjoernLaemmerzahl: Deine Variablennamen sind allesamt schlecht. So kann man gar nicht verstehen, was das bedeuten soll. Objekte sind alles in Python, und was jetzt 1, 2, oder 3 bedeutet, weißt Du selbst in zwei Tagen nicht mehr. `global` sollte nicht verwendet werden, alles was eine Funktion braucht, sollte sie über ihre Argumente bekommen, und das Ergebnis als Rückgabewert zurückliefern. Eingerückt wird immer mit 4 Leerzeichen pro Ebene. `obj3` ist als Liste angelegt, wird dann aber als Wörterbuch angesprochen. Aus `d` werden die Schlüssel benutzt, die dann aber für obj1 und dict_country_data verwendet. Ganz zum Schluß verwendest Du eine for-Schleife, wo aber k und v gar nicht verwendet werden, dafür eine obj1["de"], das in Deinen Beispieldaten gar nicht existiert. Alles sehr verwirrend.

Fang am besten Schritt für Schritt an. Was ist Dein Problem, welche Schritte sind für die Lösung nötig, wie sieht der erste davon aus?
BjoernLaemmerzahl
User
Beiträge: 22
Registriert: Sonntag 17. Mai 2015, 12:22

Hallo Sirius3,

Danke fuer deine Antwort. Ich versuche mir deine Empfehlunge zu Herzen zu nehmen. Fangen wir mit der Problemstellung an. Ich habe ein Dictionary und einen DataFrame. Ich moechte alle Spalten entsprechend den Werten in meinem Dictionary filtern und in einem neuem DataFrame speichern.
Mein Ansatz ist, dass ich alle Keys auf einer Ebene nach Werten durchsuche und dann ueberpruefe ob bereits ein DataFrame besteht. Besteht er nicht, wird einer erstellt, ansonsten wird eine Spalte angefuegt.
Nach deinen Anregungen sieht mein Code so aus:

Code: Alles auswählen

dict_country_data= {"A":
                         {"name":"A",
                          "production":
                             {"wind": 111, "solar": 222},
                          "consumption":
                              {"demand": 333}
                          },
                     "B":
                         {"name":"B",
                          "production":{"wind": 444, "solar": 555},
                          "consumption":
                              {"demand": 666}},

DataFrame mit Namen raw_data

Code: Alles auswählen

   111   222 333 444 555 666 ...
1      5   6   7   8   9   
2      5   6   7   8   9
3      5   6   ...
4      5   ...
5      5
6      5
7      5
8      5
9      5
10      5
11      5

Code: Alles auswählen

def MatchDictToFrame(source_dict, source_df, target_df):
  for k, v in source_dict.items():
    if isinstance(v, dict):
        pass
    else:
        if target_df is not None:
            target_df[v] = pd.DataFrame(source_df[v])
            return target_df
        else:
            df[v] = source_df[v]
            return target_df
            print("does  exist")


country_tightness = MatchDictToFrame(dict_country_data["de"]["production"], raw_data, country_tightness)

ich habe "global" entfernt und als Argument an die Funktion angefuegt. Der Code funktioniert allerdings nur fuer den ersten Value. Die restlichen werden nicht angefuegt. Mal sehen, ob ich dass noch herausfinde.
BjoernLaemmerzahl
User
Beiträge: 22
Registriert: Sonntag 17. Mai 2015, 12:22

Na, manchmal kann die Loesung doch so Nahe sein:

Code: Alles auswählen

def MatchDictToFrame(source_dict, source_df, target_df):
    for k, v in source_dict.items():
        if isinstance(v, dict):
            pass
        else:
            if target_df is not None:
                target_df[v] = pd.DataFrame(source_df[v])

            else:
                df[v] = source_df[v]

    return target_df

Scheint zu funktionieren.
Antworten