Ich habe eine Liste von Wörterbüchern wie folgt:
[{'points': 50, 'time': '5:00', 'year': 2010},
{'points': 25, 'time': '6:00', 'month': "february"},
{'points':90, 'time': '9:00', 'month': 'january'},
{'points_h1':20, 'month': 'june'}]
Und ich möchte daraus ein pandas DataFrame
machen:
month points points_h1 time year
0 NaN 50 NaN 5:00 2010
1 february 25 NaN 6:00 NaN
2 january 90 NaN 9:00 NaN
3 june NaN 20 NaN NaN
Hinweis: Die Reihenfolge der Spalten spielt keine Rolle.
Wie kann ich die Liste der Wörterbücher in einen pandas DataFrame umwandeln, wie oben gezeigt?
Angenommen, d
ist Ihre Liste von Dikten, einfach:
pd.DataFrame(d)
In pandas 16.2 musste ich pd.DataFrame.from_records(d)
ausführen, damit dies funktionierte.
Wie konvertiere ich eine Liste von Wörterbüchern in einen pandas DataFrame?
Die anderen Antworten sind korrekt, es wurde jedoch nicht viel über die Vor- und Nachteile dieser Methoden erklärt. Ziel dieses Beitrags ist es, Beispiele für diese Methoden in verschiedenen Situationen zu zeigen, zu erörtern, wann sie verwendet werden sollen (und wann nicht) und Alternativen vorzuschlagen.
DataFrame()
, DataFrame.from_records()
und .from_dict()
Abhängig von der Struktur und dem Format Ihrer Daten gibt es Situationen, in denen entweder alle drei Methoden funktionieren oder einige besser als andere funktionieren oder einige überhaupt nicht funktionieren.
Betrachten Sie ein sehr ausgeklügeltes Beispiel.
_np.random.seed(0)
data = pd.DataFrame(
np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')
print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
_
Diese Liste besteht aus "Datensätzen" mit allen vorhandenen Schlüsseln. Dies ist der einfachste Fall, dem Sie begegnen könnten.
_# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
_
orient='index'
_/_'columns'
_ Bevor Sie fortfahren, ist es wichtig, zwischen den verschiedenen Arten der Wörterbuchorientierung und der Unterstützung durch Pandas zu unterscheiden. Es gibt zwei Haupttypen: "Spalten" und "Index".
_orient='columns'
_
Wörterbücher mit der Ausrichtung "Spalten" entsprechen mit ihren Schlüsseln den Spalten im entsprechenden DataFrame.
Beispielsweise befindet sich data
oben in der Ausrichtung "Spalten".
_data_c = [
{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
_
_pd.DataFrame.from_dict(data_c, orient='columns')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
_
Hinweis: Wenn Sie _pd.DataFrame.from_records
_ verwenden, wird angenommen, dass die Ausrichtung "Spalten" ist (Sie können nichts anderes angeben), und die Wörterbücher werden entsprechend geladen.
_orient='index'
_
In diesem Orient wird angenommen, dass die Schlüssel den Indexwerten entsprechen. Diese Art von Daten ist am besten für _pd.DataFrame.from_dict
_ geeignet.
_data_i ={
0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
_
_pd.DataFrame.from_dict(data_i, orient='index')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
_
Dieser Fall wird im OP nicht berücksichtigt, ist aber dennoch nützlich zu wissen.
Wenn Sie einen benutzerdefinierten Index für den resultierenden DataFrame benötigen, können Sie diesen mit dem Argument _index=...
_ festlegen.
_pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])
A B C D
a 5 0 3 3
b 7 9 3 5
c 2 4 7 6
_
Dies wird von _pd.DataFrame.from_dict
_ nicht unterstützt.
Alle Methoden sind sofort einsatzbereit, wenn Wörterbücher mit fehlenden Schlüsseln/Spaltenwerten verarbeitet werden. Zum Beispiel,
_data2 = [
{'A': 5, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'F': 5},
{'B': 4, 'C': 7, 'E': 6}]
_
_# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)
A B C D E F
0 5.0 NaN 3.0 3.0 NaN NaN
1 7.0 9.0 NaN NaN NaN 5.0
2 NaN 4.0 7.0 NaN 6.0 NaN
_
"Was ist, wenn ich nicht in jeder einzelnen Spalte lesen möchte?" Sie können dies einfach mit dem Parameter _columns=...
_ angeben.
Wenn Sie beispielsweise aus dem obigen Beispielwörterbuch von _data2
_ nur die Spalten "A", "D" und "F" lesen möchten, können Sie dies tun, indem Sie eine Liste übergeben:
_pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])
A D F
0 5.0 3.0 NaN
1 7.0 NaN 5.0
2 NaN NaN NaN
_
Dies wird von _pd.DataFrame.from_dict
_ mit den Standardorientierungs- "Spalten" nicht unterstützt.
_pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])
_
_ValueError: cannot use columns parameter with orient='columns'
_
Wird von keiner dieser Methoden direkt unterstützt. Sie müssen Ihre Daten iterieren und ein mgekehrtes Löschen ausführen, während Sie iterieren. Zum Beispiel, um nur die 0 zu extrahierenth und 2nd Zeilen aus _data2
_ können Sie verwenden:
_rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
if i not in rows_to_select:
del data2[i]
pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
_
json_normalize
für verschachtelte DatenEine starke und robuste Alternative zu den oben beschriebenen Methoden ist die Funktion _json_normalize
_, die mit Listen von Wörterbüchern (Datensätzen) arbeitet und darüber hinaus auch verschachtelte Wörterbücher verarbeiten kann.
_pd.io.json.json_normalize(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
_
_pd.io.json.json_normalize(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
_
Beachten Sie auch hier, dass die an _json_normalize
_ übergebenen Daten im Format der Wörterbücher (Datensätze) vorliegen müssen.
Wie bereits erwähnt, kann _json_normalize
_ auch verschachtelte Wörterbücher verarbeiten. Hier ist ein Beispiel aus der Dokumentation.
_data_nested = [
{'counties': [{'name': 'Dade', 'population': 12345},
{'name': 'Broward', 'population': 40000},
{'name': 'Palm Beach', 'population': 60000}],
'info': {'governor': 'Rick Scott'},
'shortname': 'FL',
'state': 'Florida'},
{'counties': [{'name': 'Summit', 'population': 1234},
{'name': 'Cuyahoga', 'population': 1337}],
'info': {'governor': 'John Kasich'},
'shortname': 'OH',
'state': 'Ohio'}
]
_
_pd.io.json.json_normalize(data_nested,
record_path='counties',
meta=['state', 'shortname', ['info', 'governor']])
name population state shortname info.governor
0 Dade 12345 Florida FL Rick Scott
1 Broward 40000 Florida FL Rick Scott
2 Palm Beach 60000 Florida FL Rick Scott
3 Summit 1234 Ohio OH John Kasich
4 Cuyahoga 1337 Ohio OH John Kasich
_
Weitere Informationen zu den Argumenten meta
und _record_path
_ finden Sie in der Dokumentation.
Hier finden Sie eine Tabelle aller oben beschriebenen Methoden sowie die unterstützten Funktionen.
* Verwenden Sie _orient='columns'
_ und transponieren Sie dann, um den gleichen Effekt wie _orient='index'
_ zu erzielen.
Sie können pd.DataFrame.from_dict(d)
auch verwenden als:
In [8]: d = [{'points': 50, 'time': '5:00', 'year': 2010},
...: {'points': 25, 'time': '6:00', 'month': "february"},
...: {'points':90, 'time': '9:00', 'month': 'january'},
...: {'points_h1':20, 'month': 'june'}]
In [12]: pd.DataFrame.from_dict(d)
Out[12]:
month points points_h1 time year
0 NaN 50.0 NaN 5:00 2010.0
1 february 25.0 NaN 6:00 NaN
2 january 90.0 NaN 9:00 NaN
3 june NaN 20.0 NaN NaN
Ich weiß, ein paar Leute werden darauf stoßen und finden, dass hier nichts hilft. Der einfachste Weg, den ich gefunden habe, ist wie folgt:
dict_count = len(dict_list)
df = pd.DataFrame(dict_list[0], index=[0])
for i in range(1,dict_count-1):
df = df.append(dict_list[i], ignore_index=True)
Hoffe das hilft jemandem!