2017-10-18 97 views
2

所以我从CSV文件中的数据框大熊猫看起来像这样:Python Pandas 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), ... ] 

国家数对的每一行的第4列中的数字是不相同的。
我想扩大在第4列的列表中,并转化数据框弄成这个样子:

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

我的想法是,产生2个独立的列,然后将它们加入到原始数据帧。也许事情是这样的:

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) 

上面的代码是绝对不工作(我只希望它可以帮助表达我的想法),我不知道如何扩大日期列也是如此。
任何帮助或建议非常感谢。

回答

0

解决问题的最简单方法可能是对包含在数据框中的元组进行迭代,并创建一个新的元组。你可以用两个嵌套for循环来完成。

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']) 

如果列表中的第四场是不是一个实际的列表,但一个字符串(在数据帧例如双引号离开我有些疑惑),你可以使用literal_eval功能从ast库:Converting a string representation of a list into an actual list object

+0

非常感谢您!我会尝试这种方式,看看它是否有效。 –

+0

你是对的 - 第四列不是一个实际的列表,而是一个字符串,你的方法确实可以解决日期问题。谢谢! –

0

用途:

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

谢谢!我试过了,这正是我需要的。 –

+0

顺便说一句,我发现日期有问题,问题可能是与rejoin部分。如果我找到如何更正它,我会更新。 –

0

所以,你需要的是与值列表分成多个行cconvert列。一种解决方案是创建一个新的数据帧,并做了左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 

最后,使用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 

信用:https://stackoverflow.com/a/39955283/2314737

+0

谢谢!我也会尝试这种方式。 –

相关问题