Цепочка из pd.Series
проста для понимания, также, если вы хотите узнать больше методов, отметьте unnesting
df.set_index(['name','id']).apps.apply(pd.Series).\
stack().apply(pd.Series).\
reset_index(level=[0,1]).\
rename(columns={0:'app_name',1:'app_version'})
Out[541]:
name id app_name app_version
0 john 1 app1 v1
1 john 1 app2 v2
2 john 1 app3 v3
0 smith 2 app1 v1
1 smith 2 app4 v4
Второй способ немного изменить написанную мной функцию
def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: sum(df[x].tolist(),[])}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
Тогда
yourdf=unnesting(df,['apps'])
yourdf['app_name'],yourdf['app_version']=yourdf.apps.str[0],yourdf.apps.str[1]
yourdf
Out[548]:
apps id name app_name app_version
0 [app1, v1] 1 john app1 v1
0 [app2, v2] 1 john app2 v2
0 [app3, v3] 1 john app3 v3
1 [app1, v1] 2 smith app1 v1
1 [app4, v4] 2 smith app4 v4
Или
yourdf=unnesting(df,['apps']).reindex(columns=df.columns.tolist()+['app_name','app_version'])
yourdf[['app_name','app_version']]=yourdf.apps.tolist()
yourdf
Out[567]:
apps id name app_name app_version
0 [app1, v1] 1 john app1 v1
0 [app2, v2] 1 john app2 v2
0 [app3, v3] 1 john app3 v3
1 [app1, v1] 2 smith app1 v1
1 [app4, v4] 2 smith app4 v4