我的解决方案是使用df1.loc[i, col_name] 逐个单元格地构建新的df1 的蛮力方法。
import pandas as pd
df= pd.DataFrame({'feat': [[["str1","", 3], ["str3","", 5], ["str4","", 3]],[["str1","", 4], ["str2","", 5]] ]})
df1 = pd.DataFrame()
for i in range(df.shape[0]):
for e in df.loc[i, 'feat']:
df1.loc[i, e[0]] = e[2]
print(df1)
输出(不按列顺序):
str1 str3 str4 str2
0 3.0 5.0 3.0 NaN
1 4.0 NaN NaN 5.0
所花费的时间是
import timeit
timeit.timeit('''
import pandas as pd
df= pd.DataFrame({'feat': [[["str1","", 3], ["str3","", 5], ["str4","", 3]],[["str1","", 4], ["str2","", 5]] ]})
df1 = pd.DataFrame()
for i in range(df.shape[0]):
for e in df.loc[i, 'feat']:
df1.loc[i, e[0]] = e[2]
''', number=10000)
19.209370899999996
所以 10K 运行大约需要 20 秒。我很想知道其他算法的表现如何。也请自行运行它,因为所花费的时间因不同的电脑.并且也随着不同的数据集.他们来了:
#来自@ifly6 的回答
import timeit
timeit.timeit('''
import pandas as pd
import numpy as np
df= pd.DataFrame({'feat': [[["str1","", 3], ["str3","", 5], ["str4","", 3]],[["str1","", 4], ["str2","", 5]] ]})
df1 = pd.DataFrame.from_records(df.explode('feat').values.flatten()).replace('', np.nan)
df1.index = df.explode('feat').index
df1 = df1.reset_index().set_index(['index', 0]).unstack().dropna(how='all', axis=1)
''', number=10000)
48.217678400000295
#来自@Naveed 的回答
import timeit
timeit.timeit('''
import pandas as pd
df= pd.DataFrame({'feat': [[["str1","", 3], ["str3","", 5], ["str4","", 3]],[["str1","", 4], ["str2","", 5]] ]})
df = df.explode('feat')
df[['col1','col3','col2']] = df['feat'].astype('str').replace('[\[\]]','', regex=True).str.split(',', expand=True)
df = df.reset_index()
df = df.pivot(index='index', columns='col1', values='col2')
''', number=10000)
34.94540550000056
#来自@BeRT2me 的回答(不用df = df[df.columns.sort_values()] 重新排列列会更快)
import timeit
timeit.timeit('''
import pandas as pd
df= pd.DataFrame({'feat': [[["str1","", 3], ["str3","", 5], ["str4","", 3]],[["str1","", 4], ["str2","", 5]] ]})
df = df.feat.apply(lambda val: pd.Series({y[0]:y[2] for y in val}))
df = df[df.columns.sort_values()]
''', number=10000)
12.745890199999849