2017-02-16 2 views
2

Vor diesem DataFrame:Pandas: ein Wörterbuch mit einer Liste von Spalten erstellen als Werte

import pandas as pd 
first=[0,1,2,3,4] 
second=[10.2,5.7,7.4,17.1,86.11] 
third=['a','b','c','d','e'] 
fourth=['z','zz','zzz','zzzz','zzzzz'] 
df=pd.DataFrame({'first':first,'second':second,'third':third,'fourth':fourth}) 
df=df[['first','second','third','fourth']] 

    first second third fourth 
0  0 10.20  a  z 
1  1 5.70  b  zz 
2  2 7.40  c zzz 
3  3 17.10  d zzzz 
4  4 86.11  e zzzzz 

ein Wörterbuch aus df mit erstellen

a=df.set_index('first')['second'].to_dict() 

, damit ich entscheiden kann, was keys ist und was ist values. Aber was, wenn Sie möchten, dass values eine Liste von Spalten ist, wie second AND third?

Wenn ich versuche, dieses

b=df.set_index('first')[['second','third']].to_dict() 

ich ein seltsames Wörterbuch der Wörterbücher

{'second': {0: 10.199999999999999, 
    1: 5.7000000000000002, 
    2: 7.4000000000000004, 
    3: 17.100000000000001, 
    4: 86.109999999999999}, 
'third': {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}} 

Stattdessen möchte ich ein Wörterbuch von Listen

{0: [10.199999999999999,a], 
1: [5.7000000000000002,b], 
2: [7.4000000000000004,c], 
3: [17.100000000000001,d], 
4: [86.109999999999999,e]} 

Wie damit umgehen ?

Antwort

2

Jemand anderes kann wahrscheinlich mit einer puren Pandas-Lösung plaudern, aber im Notfall denke ich, dass dies für Sie funktionieren sollte. Sie würden das Wörterbuch im Grunde sofort erstellen und stattdessen Werte in jeder Zeile indizieren.

d = {df.loc[idx, 'first']: [df.loc[idx, 'second'], df.loc[idx, 'third']] for idx in range(df.shape[0])} 

d 
Out[5]: 
{0: [10.199999999999999, 'a'], 
1: [5.7000000000000002, 'b'], 
2: [7.4000000000000004, 'c'], 
3: [17.100000000000001, 'd'], 
4: [86.109999999999999, 'e']} 

Edit: Sie können auch dies tun:

df['new'] = list(zip(df['second'], df['third'])) 

df 
Out[25]: 
    first second third fourth   new 
0  0 10.20  a  z (10.2, a) 
1  1 5.70  b  zz (5.7, b) 
2  2 7.40  c zzz (7.4, c) 
3  3 17.10  d zzzz (17.1, d) 
4  4 86.11  e zzzzz (86.11, e) 

df = df[['first', 'new']] 

df 
Out[27]: 
    first   new 
0  0 (10.2, a) 
1  1 (5.7, b) 
2  2 (7.4, c) 
3  3 (17.1, d) 
4  4 (86.11, e) 

df.set_index('first').to_dict() 
Out[28]: 
{'new': {0: (10.199999999999999, 'a'), 
    1: (5.7000000000000002, 'b'), 
    2: (7.4000000000000004, 'c'), 
    3: (17.100000000000001, 'd'), 
    4: (86.109999999999999, 'e')}} 

Bei diesem Ansatz würden Sie zuerst die Liste (oder Tupel) erstellen, möchten Sie halten und „drop“ die anderen Spalten dann. Dies ist im Grunde Ihr ursprünglicher Ansatz, modifiziert.

Und wenn man wirklich will, Listen anstelle von Tupeln, map nur die list Art auf diese 'new' Säule:

df['new'] = list(map(list, zip(df['second'], df['third']))) 
+0

Meine echte "erste" ist eine Spalte von Zahlen als "Strings" (alphanumerische Werte, in aller Ehrlichkeit) codiert. Wenn sie in das Wörterbuch übertragen werden, erscheinen sie wie 'u'112233'. Wie man dieses "u" (Unicode) loswird? – FaCoffee

+1

Das 'du' beeinflusst nicht wirklich die "Integrität" dieser Strings, aber wenn du es weg haben willst, würde ich 'map (str, df ['first'])' 'versuchen. Oder auch 'df ['first'] = [str (x) für x in df ['first']]' – blacksite

+0

Dies sollte wahrscheinlich als separate Frage gehen, aber was ist, wenn Sie das Tupel '(first, second)' wollen als Schlüssel des Wörterbuchs? – FaCoffee

1

Sie können erstellen numpy array von values, zip durch Spalte first und konvertieren dict:

a = dict(zip(df['first'], df[['second','third']].values.tolist())) 
print (a) 
{0: [10.2, 'a'], 1: [5.7, 'b'], 2: [7.4, 'c'], 3: [17.1, 'd'], 4: [86.11, 'e']} 
1

Sie können zip die Werte:

In [118]: 
b=df.set_index('first')[['second','third']].values.tolist() 
dict(zip(df['first'].index,b)) 

Out[118]: 
{0: [10.2, 'a'], 1: [5.7, 'b'], 2: [7.4, 'c'], 3: [17.1, 'd'], 4: [86.11, 'e']} 
Verwandte Themen