Konvertieren Sie einen Pandas DataFrame in ein Wörterbuch


168

Ich habe einen DataFrame mit vier Spalten. Ich möchte diesen DataFrame in ein Python-Wörterbuch konvertieren. Ich möchte, dass die Elemente der ersten Spalte keysund die Elemente anderer Spalten in derselben Zeile sind values.

DataFrame:

    ID   A   B   C
0   p    1   3   2
1   q    4   3   2
2   r    4   0   9  

Die Ausgabe sollte folgendermaßen aussehen:

Wörterbuch:

{'p': [1,3,2], 'q': [4,3,2], 'r': [4,0,9]}

4
Dataframe.to_dict()?
Anzel

3
Dataframe.to_dict()wird A,B,Cdie Schlüssel anstelle vonp,q,r
Prinz Bhatti

@jezrael wie bekomme ich die folgende Ausgabe? {2: {'p': [1,3]}, 2: {'q': [4,3]}, 9: {'r': [4,0]}} für denselben Datensatz?
Panda

@jezrael Spaltenäquivalente der obigen Frage {'c': {'ID': 'A', 'B'}}
Panda

Antworten:


337

Die to_dict()Methode legt die Spaltennamen als Wörterbuchschlüssel fest, sodass Sie Ihren DataFrame leicht umformen müssen. Das Festlegen der Spalte 'ID' als Index und das anschließende Transponieren des DataFrame ist eine Möglichkeit, dies zu erreichen.

to_dict()Akzeptiert auch ein 'orient'-Argument, das Sie benötigen, um eine Liste von Werten für jede Spalte auszugeben . Andernfalls {index: value}wird für jede Spalte ein Wörterbuch des Formulars zurückgegeben.

Diese Schritte können mit der folgenden Zeile ausgeführt werden:

>>> df.set_index('ID').T.to_dict('list')
{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

Falls ein anderes Wörterbuchformat benötigt wird, finden Sie hier Beispiele für mögliche Orientierungsargumente. Betrachten Sie den folgenden einfachen DataFrame:

>>> df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
>>> df
        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Dann sind die Optionen wie folgt.

dict - die Standardeinstellung: Spaltennamen sind Schlüssel, Werte sind Wörterbücher von Index: Datenpaaren

>>> df.to_dict('dict')
{'a': {0: 'red', 1: 'yellow', 2: 'blue'}, 
 'b': {0: 0.5, 1: 0.25, 2: 0.125}}

Liste - Tasten sind Spaltennamen, Werte sind Listen von Spaltendaten

>>> df.to_dict('list')
{'a': ['red', 'yellow', 'blue'], 
 'b': [0.5, 0.25, 0.125]}

Serien - wie 'Liste', aber Werte sind Serien

>>> df.to_dict('series')
{'a': 0       red
      1    yellow
      2      blue
      Name: a, dtype: object, 

 'b': 0    0.500
      1    0.250
      2    0.125
      Name: b, dtype: float64}

Teilt - teilt Spalten / Daten / Index als Schlüssel auf, wobei Werte Spaltennamen, Datenwerte nach Zeilen- bzw. Indexbezeichnungen sind

>>> df.to_dict('split')
{'columns': ['a', 'b'],
 'data': [['red', 0.5], ['yellow', 0.25], ['blue', 0.125]],
 'index': [0, 1, 2]}

Aufzeichnungen - Jede Zeile wird zu einem Wörterbuch, in dem der Schlüssel der Spaltenname und der Wert die Daten in der Zelle sind

>>> df.to_dict('records')
[{'a': 'red', 'b': 0.5}, 
 {'a': 'yellow', 'b': 0.25}, 
 {'a': 'blue', 'b': 0.125}]

indexähnliche 'Datensätze', aber ein Wörterbuch mit Wörterbüchern mit Schlüsseln als Indexbezeichnungen (anstelle einer Liste)

>>> df.to_dict('index')
{0: {'a': 'red', 'b': 0.5},
 1: {'a': 'yellow', 'b': 0.25},
 2: {'a': 'blue', 'b': 0.125}}

14
Dies wird ein Liner sein:df.set_index('ID').T.to_dict('list')
Anzel

1
Für einen Datensatz im Datenrahmen. df.T.to_dict () [0]
Kamran Kausar

23

Versuchen zu benutzen Zip

df = pd.read_csv("file")
d= dict([(i,[a,b,c ]) for i, a,b,c in zip(df.ID, df.A,df.B,df.C)])
print d

Ausgabe:

{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}

21

Folge diesen Schritten:

Angenommen, Ihr Datenrahmen lautet wie folgt:

>>> df
   A  B  C ID
0  1  3  2  p
1  4  3  2  q
2  4  0  9  r

1. Verwenden Sie set_indexdiese IDOption , um Spalten als Datenrahmenindex festzulegen.

    df.set_index("ID", drop=True, inplace=True)

2. Verwenden Sie den orient=indexParameter, um den Index als Wörterbuchschlüssel zu verwenden.

    dictionary = df.to_dict(orient="index")

Die Ergebnisse werden wie folgt sein:

    >>> dictionary
    {'q': {'A': 4, 'B': 3, 'D': 2}, 'p': {'A': 1, 'B': 3, 'D': 2}, 'r': {'A': 4, 'B': 0, 'D': 9}}

3. Wenn Sie jedes Beispiel als Liste haben möchten, führen Sie den folgenden Code aus. Bestimmen Sie die Spaltenreihenfolge

column_order= ["A", "B", "C"] #  Determine your preferred order of columns
d = {} #  Initialize the new dictionary as an empty dictionary
for k in dictionary:
    d[k] = [dictionary[k][column_name] for column_name in column_order]

2
Für das letzte Bit scheint es einfacher zu sein, ein Diktatverständnis zu verwenden, um das for-Schleifen- + Listenverständnis zu ersetzen (3 Zeilen -> 1). In jedem Fall ist die Top-Antwort viel kürzer, obwohl es schön ist, Optionen zu haben.
fantastisch

Dies ist praktisch, da hier klar erläutert wird, wie eine bestimmte Spalte oder Überschrift als Index verwendet wird.
Tropicalrambler

10

Wenn es Ihnen nichts ausmacht, dass die Wörterbuchwerte Tupel sind, können Sie itertuples verwenden:

>>> {x[0]: x[1:] for x in df.itertuples(index=False)}
{'p': (1, 3, 2), 'q': (4, 3, 2), 'r': (4, 0, 9)}

7

sollte ein Wörterbuch wie:

{'red': '0.500', 'yellow': '0.250, 'blue': '0.125'}

aus einem Datenrahmen erforderlich sein wie:

        a      b
0     red  0.500
1  yellow  0.250
2    blue  0.125

Der einfachste Weg wäre:

dict(df.values.tolist())

Arbeitsausschnitt unten:

import pandas as pd
df = pd.DataFrame({'a': ['red', 'yellow', 'blue'], 'b': [0.5, 0.25, 0.125]})
dict(df.values.tolist())

Geben Sie hier die Bildbeschreibung ein


2

Für meine Verwendung (Knotennamen mit xy-Positionen) fand ich die Antwort von @ user4179775 auf die hilfreichste / intuitivste:

import pandas as pd

df = pd.read_csv('glycolysis_nodes_xy.tsv', sep='\t')

df.head()
    nodes    x    y
0  c00033  146  958
1  c00031  601  195
...

xy_dict_list=dict([(i,[a,b]) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_list
{'c00022': [483, 868],
 'c00024': [146, 868],
 ... }

xy_dict_tuples=dict([(i,(a,b)) for i, a,b in zip(df.nodes, df.x,df.y)])

xy_dict_tuples
{'c00022': (483, 868),
 'c00024': (146, 868),
 ... }

Nachtrag

Ich kehrte später zu diesem Thema zurück, um andere, aber verwandte Arbeiten zu erledigen. Hier ist ein Ansatz, der die [ausgezeichnete] akzeptierte Antwort genauer widerspiegelt.

node_df = pd.read_csv('node_prop-glycolysis_tca-from_pg.tsv', sep='\t')

node_df.head()
   node  kegg_id kegg_cid            name  wt  vis
0  22    22       c00022   pyruvate        1   1
1  24    24       c00024   acetyl-CoA      1   1
...

Konvertieren Sie den Pandas-Datenrahmen in eine [Liste], {dict}, {dict of {dict}}, ...

Pro akzeptierter Antwort:

node_df.set_index('kegg_cid').T.to_dict('list')

{'c00022': [22, 22, 'pyruvate', 1, 1],
 'c00024': [24, 24, 'acetyl-CoA', 1, 1],
 ... }

node_df.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'kegg_id': 22, 'name': 'pyruvate', 'node': 22, 'vis': 1, 'wt': 1},
 'c00024': {'kegg_id': 24, 'name': 'acetyl-CoA', 'node': 24, 'vis': 1, 'wt': 1},
 ... }

In meinem Fall wollte ich dasselbe tun, aber mit ausgewählten Spalten aus dem Pandas-Datenrahmen, also musste ich die Spalten in Scheiben schneiden. Es gibt zwei Ansätze.

  1. Direkt:

(Siehe: Konvertieren Sie Pandas in ein Wörterbuch, in dem die für die Schlüsselwerte verwendeten Spalten definiert sind. )

node_df.set_index('kegg_cid')[['name', 'wt', 'vis']].T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }
  1. "Indirekt:" Schneiden Sie zuerst die gewünschten Spalten / Daten aus dem Pandas-Datenrahmen (wieder zwei Ansätze).
node_df_sliced = node_df[['kegg_cid', 'name', 'wt', 'vis']]

oder

node_df_sliced2 = node_df.loc[:, ['kegg_cid', 'name', 'wt', 'vis']]

Damit kann dann ein Wörterbuch mit Wörterbüchern erstellt werden

node_df_sliced.set_index('kegg_cid').T.to_dict('dict')

{'c00022': {'name': 'pyruvate', 'vis': 1, 'wt': 1},
 'c00024': {'name': 'acetyl-CoA', 'vis': 1, 'wt': 1},
 ... }

-1

DataFrame.to_dict() konvertiert DataFrame in ein Wörterbuch.

Beispiel

>>> df = pd.DataFrame(
    {'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b'])
>>> df
   col1  col2
a     1   0.1
b     2   0.2
>>> df.to_dict()
{'col1': {'a': 1, 'b': 2}, 'col2': {'a': 0.5, 'b': 0.75}}

Weitere Informationen finden Sie in dieser Dokumentation


2
Ja, aber das OP hat ausdrücklich angegeben, dass die Zeilenindizes die Schlüssel und nicht die Spaltenbezeichnungen sein sollen.
Vicki B
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.