it-swarm.com.de

Konvertiert eine Liste von Wörterbüchern in einen pandas DataFrame

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?

502
appleLover

Angenommen, d ist Ihre Liste von Dikten, einfach:

pd.DataFrame(d)
732
joris

In pandas 16.2 musste ich pd.DataFrame.from_records(d) ausführen, damit dies funktionierte.

76
szeitlin

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
_

Wort auf Wörterbuch-Orientierungen: _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.

Festlegen des benutzerdefinierten Index

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.

Umgang mit fehlenden Schlüsseln/Spalten

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
_

Lesen einer Teilmenge von Spalten

"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'
_

Lesen einer Teilmenge von Zeilen

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
_

Das Allheilmittel: json_normalize für verschachtelte Daten

Eine 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.


Zusammenfassen

Hier finden Sie eine Tabelle aller oben beschriebenen Methoden sowie die unterstützten Funktionen.

enter image description here

* Verwenden Sie _orient='columns'_ und transponieren Sie dann, um den gleichen Effekt wie _orient='index'_ zu erzielen.

72
cs95

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
18
shivsn

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!

0
scottapotamus