将包含字典的 Pandas 列转换为多行

4
我有这个数据框:
``` temp = pd.DataFrame({'Person': ['P1', 'P2'], 'Dictionary': [{'value1': 0.31, 'value2': 0.304}, {'value2': 0.324}]}) ```
  Person                    Dictionary    
0  P1  {'value1': 0.31, 'value2': 0.304}
1  P2                  {'value2': 0.324}

我想要这种格式的输出:
temp1 = pd.DataFrame({'Person': ['P1', 'P1', 'P2'], 'Values_Number': ['value1', 'value2', 'value2'], 'Values': [0.31, 0.304, 0.324]})

我尝试使用这个:
temp['Dictionary'].apply(pd.Series).T.reset_index()

  Person Values_Number  Values
0     P1        value1   0.310
1     P1        value2   0.304
2     P2        value2   0.324

但是我无法将其与先前的数据框连接起来。此外,可能会出现错误的机会。
2个回答

5

如果我理解得正确的话,我们可以使用Series.tolist来构建一个新的DataFrame,然后使用DataFrame.melt进行melt

new_df = (pd.DataFrame(temp['Dictionary'].tolist(), index=temp['Person'])
            .reset_index()
            .melt('Person', var_name='Values_Number', value_name='Values')
            .dropna()
            .reset_index(drop=True))
print(new_df)

  Person Values_Number  Values
0     P1        value1   0.310
1     P1        value2   0.304
2     P2        value2   0.324

使用pd.DataFrame(df['Dictionary'].tolist())比使用.apply(pd.Series)更加高效。关于何时在代码中使用apply,您可以在这里查看。


这是在本文中使用apply(pd.Series)得到的结果。

%timeit s.apply(pd.Series)
%timeit pd.DataFrame(s.tolist())

2.65 ms ± 294 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
816 µs ± 40.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

0

结合使用 tolistmelt 应该可以解决问题

pd.DataFrame(df['Dictionary'].tolist()).set_index(temp['per']).reset_index().melt(id_vars='Person', value_vars=['value1', 'value2'], var_name='Values_Number').dropna()

  Person Values_Number  value
0  P1    value1         0.310
2  P1    value2         0.304
3  P2    value2         0.324

1
https://dev59.com/h1QJ5IYBdhLWcg3wKykQ - ansev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接