2017-10-18 3 views
2

So habe ich einen Pandas Datenrahmen aus CSV-Datei wie folgt aussieht:Python Pandas Dataframe: Wie erstellt man Spalten aus einer bestehenden Liste im Dataframe?

year,month,day,list 
2017,09,01,"[('United States of America', 12345), (u'Germany', 54321), (u'Switzerland', 13524), (u'Netherlands', 24135), ... ] 
2017,09,02,"[('United States of America', 6789), (u'Germany', 9876), (u'Switzerland', 6879), (u'Netherlands', 7968), ... ] 

Die Zahl der Land-count-Paare in der vierten Spalte jeder Zeile nicht identisch ist.
Ich mag die Liste in der vierten Spalte zu erweitern, und den Datenrahmen in so etwas wie diese Transformation:

year,month,day,country,count 
2017,09,01,'United States of America',12345 
2017,09,01,'Germany',54321 
2017,09,01,'Switzerland',13524 
2017,09,01,'Netherlands',24135 
... 
2017,09,02,'United States of America',6789 
2017,09,02,'Germany',9876 
2017,09,02,'Switzerland',6879 
2017,09,02,'Netherlands',7968 
... 

Mein Gedanke war, 2 unabhängige Spalten zu erzeugen, kommen sie dann zum Ursprung Datenrahmen. Vielleicht so etwas wie folgt aus:

country = df.apply(lambda x:[x['list'][0]]).stack().reset_index(level=1, drop=True) 
count = df.apply(lambda x:[x['list'][1]]).stack().reset_index(level=1, drop=True) 
df.drop('list', axis=1).join(country).join(count) 

Der obige Code ist auf jeden Fall nicht funktioniert (ich hoffe nur, dass es meine Gedanken ausdrücken helfen), und ich habe keine Ahnung, wie die Datumsspalten zu erweitern als auch.
Jede Hilfe oder Anregung wird sehr geschätzt.

Antwort

0

Wahrscheinlich ist der einfachste Weg, um Ihr Problem zu lösen, iterieren über die Tupel im Datenframe, und ein neues zu erstellen. Sie können es mit zwei verschachtelten for-Schleifen tun.

df_new = [] 
for i in df.itertuples(): 
    for l in i.list: 
     df_new.append([i.year, i.month, i.day, l[0], l[1]]) 

df_new = pd.DataFrame(df_new, columns=['year', 'month', 'day', 'country', 'count']) 

Wenn das vierte Feld der Liste nicht eine aktuelle Liste ist aber eine Zeichenfolge (die doppelten Anführungszeichen in dem Datenrahmen Beispiel lassen Sie mich einige Zweifel), können Sie die literal_eval Funktion aus der ast Bibliothek verwenden: Converting a string representation of a list into an actual list object

+0

Thank you very much! Ich werde es versuchen und sehen, ob es funktioniert. –

+0

Sie haben Recht - die 4. Spalte war keine tatsächliche Liste, sondern eine Zeichenfolge, und Ihre Methode hat das Problem mit Datum gelöst. Vielen Dank! –

0

Verwendung:

import ast 
#convert strings to lists of tuples 
df['list'] = df['list'].apply(ast.literal_eval) 
#create reshaped df from column list 
df1 =pd.DataFrame([dict(x) for x in df['list'].values.tolist()]).stack().reset_index(level=1) 
df1.columns = ['country','count'] 
#join to original 
df = df.drop('list', 1).join(df1).reset_index(drop=True) 
print (df) 
    year month day     country count 
0 2017  9 1     Germany 54321 
1 2017  9 1    Netherlands 24135 
2 2017  9 1    Switzerland 13524 
3 2017  9 1 United States of America 12345 
4 2017  9 2     Germany 9876 
5 2017  9 2    Netherlands 7968 
6 2017  9 2    Switzerland 6879 
7 2017  9 2 United States of America 6789 
+0

Danke! Ich habe es versucht und genau das brauche ich. –

+0

BTW, ich habe festgestellt, dass etwas mit dem Datum nicht stimmt, das Problem ist wahrscheinlich mit dem wiedervereinigen Teil. Ich werde aktualisieren, wenn ich herausfinden, wie ich es korrigieren kann. –

0

Also, was Sie brauchen, ist eine Spalte mit einer Liste von Werten in mehrere Zeilen cconvert. Eine Lösung ist einen neuen Datenrahmen zu erstellen und tun, um ein links join:

df = pd.DataFrame({'A':['a','b'],'B':['x','y'], 
        'C':[['a1', 'a2'],['b1', 'b2', 'b3']]}) 

df 
# A B    C 
# 0 a x  [[a1, a2]] 
# 1 b y [[b1, b2, b3]] 

dfr=df['C'].apply(lambda k: pd.Series(k)).stack().reset_index(level=1, drop=True).to_frame('C') 

dfr 
#  C 
# 0 a1 
# 0 a2 
# 1 b1 
# 1 b2 
# 1 b3 

df[['A','B']].join(dfr, how='left') 
# A B C 
# 0 a x a1 
# 0 a x a2 
# 1 b y b1 
# 1 b y b2 
# 1 b y b3 

Schließlich verwendet reset_index()

df[['A','B']].join(dfr, how='left').reset_index(drop=1) 
# A B C 
# 0 a x a1 
# 1 a x a2 
# 2 b y b1 
# 3 b y b2 
# 4 b y b3 

Credit: https://stackoverflow.com/a/39955283/2314737

+0

Danke! Ich werde es auch so versuchen. –

Verwandte Themen