Ich habe Daten in einer PostgreSQL-Datenbank gespeichert. Ich frage diese Daten mit Python2.7 ab und verwandle sie in einen Pandas DataFrame. Die letzte Spalte dieses Datenrahmens enthält jedoch ein Wörterbuch (oder eine Liste?) Mit Werten. Der DataFrame sieht folgendermaßen aus:
[1] df
Station ID Pollutants
8809 {"a": "46", "b": "3", "c": "12"}
8810 {"a": "36", "b": "5", "c": "8"}
8811 {"b": "2", "c": "7"}
8812 {"c": "11"}
8813 {"a": "82", "c": "15"}
Ich muss diese Spalte in separate Spalten aufteilen, damit der DataFrame folgendermaßen aussieht:
[2] df2
Station ID a b c
8809 46 3 12
8810 36 5 8
8811 NaN 2 7
8812 NaN NaN 11
8813 82 NaN 15
Das Hauptproblem, das ich habe, ist, dass die Listen nicht gleich lang sind. Alle Listen enthalten jedoch nur bis zu den gleichen 3 Werten: a, b und c. Und sie erscheinen immer in derselben Reihenfolge (a erste, b zweite, c dritte).
Der folgende Code wurde verwendet, um zu arbeiten und genau das zurückzugeben, was ich wollte (df2).
[3] df
[4] objs = [df, pandas.DataFrame(df['Pollutant Levels'].tolist()).iloc[:, :3]]
[5] df2 = pandas.concat(objs, axis=1).drop('Pollutant Levels', axis=1)
[6] print(df2)
Ich habe diesen Code erst letzte Woche ausgeführt und er hat gut funktioniert. Aber jetzt ist mein Code kaputt und ich bekomme diesen Fehler aus Zeile [4]:
IndexError: out-of-bounds on slice (end)
Ich habe keine Änderungen am Code vorgenommen, erhalte aber jetzt den Fehler. Ich denke, das liegt daran, dass meine Methode nicht robust oder richtig ist.
Anregungen oder Anleitungen zum Aufteilen dieser Listenspalte in separate Spalten sind sehr willkommen!
EDIT: Ich denke, die Methoden .tolist () und .apply funktionieren nicht mit meinem Code, da es sich um eine Unicode-Zeichenfolge handelt, dh:
#My data format
u{'a': '1', 'b': '2', 'c': '3'}
#and not
{u'a': '1', u'b': '2', u'c': '3'}
Die Daten werden in diesem Format aus der postgreSQL-Datenbank importiert. Hilfe oder Ideen zu diesem Thema? Gibt es eine Möglichkeit, den Unicode zu konvertieren?
quelle
iloc
Teililoc[:, :3]
davon ausgegangen wird, dass es 3 Elemente gibt, und dass neuere Datenscheiben möglicherweise nur 1 oder 2 haben (z. B. gibt es zufällig keinb
Like inindex 8813
)?Antworten:
Sie können die Zeichenfolge in ein tatsächliches Diktat konvertieren
df['Pollutant Levels'].map(eval)
. Anschließend kann die folgende Lösung verwendet werden, um das Diktat in verschiedene Spalten zu konvertieren.Anhand eines kleinen Beispiels können Sie Folgendes verwenden
.apply(pd.Series)
:Um es mit dem Rest des Datenrahmens zu kombinieren, können Sie
concat
die anderen Spalten mit dem obigen Ergebnis verwenden:Mit Ihrem Code funktioniert dies auch, wenn ich das
iloc
Teil weglasse:quelle
pd.DataFrame(df[col].tolist())
für eine lange Zeit verwendet, nie darüber nachgedachtapply(pd.Series)
. Sehr schön.DataFrame(df['col'].tolist())
Ansatz ist ziemlich viel schneller als der Apply- Ansatz!df[col].map(eval)
Diktat konvertieren, bevor Sie sie in einen DataFrame konvertierenIch weiß, dass die Frage ziemlich alt ist, aber ich bin hierher gekommen, um nach Antworten zu suchen. Es gibt tatsächlich einen besseren (und schnelleren) Weg, dies zu tun, indem man
json_normalize
:Dies vermeidet kostspielige Anwendungsfunktionen ...
quelle
.json
Dateien einbringe, stammen aus verschiedenen Quellen und es sind nicht immer dieselben Spalten, die verschachtelt sind. Ich habe versucht, einen Weg zu finden, um eine Liste von Spalten zu erstellen, die Diktate enthalten, aber es scheint nicht zu funktionierenfrom pandas.io.json import json_normalize
meta_prefix
und gibtrecord_prefix
. Ich kann das zwar nicht mit meinem Datenrahmen zum Laufen bringen (der endgültige Datenrahmen ist in meinem Fall korrekt, aber ich möchte die Präfixe anwenden).Versuchen Sie Folgendes: Die von SQL zurückgegebenen Daten müssen in ein Dict konvertiert werden. oder könnte es
"Pollutant Levels"
jetzt seinPollutants'
quelle
Merlins Antwort ist besser und super einfach, aber wir brauchen keine Lambda-Funktion. Die Auswertung des Wörterbuchs kann auf zwei der folgenden Arten ignoriert werden:
Weg 1: Zwei Schritte
Weg 2: Die beiden oben genannten Schritte können auf einmal kombiniert werden:
quelle
Ich empfehle dringend die Methode, die Spalte 'Schadstoffe' zu extrahieren:
df_pollutants = pd.DataFrame(df['Pollutants'].values.tolist(), index=df.index)
es ist viel schneller als
df_pollutants = df['Pollutants'].apply(pd.Series)
wenn die Größe von df riesig ist.
quelle
apply
der gesamte Datenrahmen von Pandas verwaltet, aber wenn es darumvalues
geht, spielt es nur mit dem,numpy ndarrays
was aufgrund der Tatsache, dass es reinec
Implementierungen hat, wesentlich schneller ist .Sie können
join
mitpop
+ verwendentolist
. Die Leistung ist vergleichbarconcat
mitdrop
+tolist
, aber einige finden diese Syntax möglicherweise sauberer:Benchmarking mit anderen Methoden:
quelle
Eine einzeilige Lösung folgt:
quelle
my_df = pd.DataFrame.from_dict(my_dict, orient='index', columns=['my_col'])
.. hätte das Diktat richtig analysiert (indem jeder Diktatschlüssel in eine separate df-Spalte und die Schlüsselwerte in df-Zeilen eingefügt wurden), sodass die Diktate überhaupt nicht in eine einzelne Spalte gequetscht würden.
quelle
Ich habe diese Schritte in einer Methode verkettet. Sie müssen nur den Datenrahmen und die Spalte übergeben, die das zu erweiternde Diktat enthält:
quelle
quelle