python3: pandas 按多列分组并将行值转换为多列
python3: pandas group by several columns and convert rows value into multiple columns
我有如下数据框:
id date t_s t_p t_prob
1 '2020-01-01' 1 1 0.5
1 '2020-01-01' 2 1 0.55
1 '2020-01-01' 3 1 0.56
1 '2020-01-01' 4 0 0.4
1 '2020-01-01' 5 1 0.6
1 '2020-01-01' 6 1 0.7
2 '2020-01-01' 1 1 0.77
2 '2020-01-01' 2 0 0.3
2 '2020-01-01' 3 0 0.2
2 '2020-01-01' 4 0 0.33
2 '2020-01-01' 5 1 0.66
2 '2020-01-01' 6 1 0.56
....
每个 ID 都有相同的日期,例如 (2020-01-01-2020-01-09)。每个id每个date有6个t_s(1,2,3,4,5,6),t_p是每个t_s的label,t_prob是每个 t_s 的标签值。我想将同一日期中每个 t_s 的 t_prob 值转换为 t_s_1、t_s_2、t_s_3、t_s_4,t_s_5,t_s_6。最后得到 t_prob 和 t_s 的最大价值。就像'2020-01-01'中的id 1是t_s_6是最有价值的。
id date t_s_1 t_s_2 t_s_3 t_s_4 t_s_5 t_s_6 t_prob_max_s
1 '2020-01-01' 0.5 0.55 0.56 0.4 0.6 0.7 6
2 '2020-01-01' 0.77 0.3 0.2 0.33 0.66 0.56 1
....
谢谢!
首先按相关索引列和要取消堆叠的列进行分组。您可以选择除“最大”聚合之外的其他内容,具体取决于上下文。如果每个都出现一次,那就没关系了。
unstacked = df.groupby(['id', 'date', 't_s'])['t_prob'].aggregate('max').unstack()
或者:
df.pivot_table(index=['id', 'date'], columns='t_s', values='t_prob', aggfunc='max')
哪个不太灵活,但在上下文中可能更清晰。
重命名轴,使列轴没有奇怪的“t_s”名称。然后重命名列,使它们枚举 t_s:
unstacked_renamed = unstacked.rename_axis(columns = None).rename(columns={val:f't_s_{val}' for val in unstacked.columns.values})
获取每行具有最高值的列的索引,然后对其进行预处理以获得与该列相关的 t_s 个数:
unstacked_renamed['t_prob_max_s'] = unstacked_renamed.idxmax(axis=1).str.split('_').str[-1]
重置指数,使其再次持平:
unstacked_reindexed = unstacked_renamed.reset_index()
检查正确性:
>>unstacked_reindexed
id date t_s_1 t_s_2 t_s_3 t_s_4 t_s_5 t_s_6 t_prob_max_s
0 1 '2020-01-01' 0.50 0.55 0.56 0.40 0.60 0.70 6
1 2 '2020-01-01' 0.77 0.30 0.20 0.33 0.66 0.56 1
即使初始数据未被索引器排序,如果给定 t_s 值多次出现(但选择的聚合是不可忽略的),或者存在 missing/skipped t_s(例如 t_s 1,2,3,4,5,7 的值)。它通常是非常强大的解决方案。
我有如下数据框:
id date t_s t_p t_prob
1 '2020-01-01' 1 1 0.5
1 '2020-01-01' 2 1 0.55
1 '2020-01-01' 3 1 0.56
1 '2020-01-01' 4 0 0.4
1 '2020-01-01' 5 1 0.6
1 '2020-01-01' 6 1 0.7
2 '2020-01-01' 1 1 0.77
2 '2020-01-01' 2 0 0.3
2 '2020-01-01' 3 0 0.2
2 '2020-01-01' 4 0 0.33
2 '2020-01-01' 5 1 0.66
2 '2020-01-01' 6 1 0.56
....
每个 ID 都有相同的日期,例如 (2020-01-01-2020-01-09)。每个id每个date有6个t_s(1,2,3,4,5,6),t_p是每个t_s的label,t_prob是每个 t_s 的标签值。我想将同一日期中每个 t_s 的 t_prob 值转换为 t_s_1、t_s_2、t_s_3、t_s_4,t_s_5,t_s_6。最后得到 t_prob 和 t_s 的最大价值。就像'2020-01-01'中的id 1是t_s_6是最有价值的。
id date t_s_1 t_s_2 t_s_3 t_s_4 t_s_5 t_s_6 t_prob_max_s
1 '2020-01-01' 0.5 0.55 0.56 0.4 0.6 0.7 6
2 '2020-01-01' 0.77 0.3 0.2 0.33 0.66 0.56 1
....
谢谢!
首先按相关索引列和要取消堆叠的列进行分组。您可以选择除“最大”聚合之外的其他内容,具体取决于上下文。如果每个都出现一次,那就没关系了。
unstacked = df.groupby(['id', 'date', 't_s'])['t_prob'].aggregate('max').unstack()
或者:
df.pivot_table(index=['id', 'date'], columns='t_s', values='t_prob', aggfunc='max')
哪个不太灵活,但在上下文中可能更清晰。
重命名轴,使列轴没有奇怪的“t_s”名称。然后重命名列,使它们枚举 t_s:
unstacked_renamed = unstacked.rename_axis(columns = None).rename(columns={val:f't_s_{val}' for val in unstacked.columns.values})
获取每行具有最高值的列的索引,然后对其进行预处理以获得与该列相关的 t_s 个数:
unstacked_renamed['t_prob_max_s'] = unstacked_renamed.idxmax(axis=1).str.split('_').str[-1]
重置指数,使其再次持平:
unstacked_reindexed = unstacked_renamed.reset_index()
检查正确性:
>>unstacked_reindexed
id date t_s_1 t_s_2 t_s_3 t_s_4 t_s_5 t_s_6 t_prob_max_s
0 1 '2020-01-01' 0.50 0.55 0.56 0.40 0.60 0.70 6
1 2 '2020-01-01' 0.77 0.30 0.20 0.33 0.66 0.56 1
即使初始数据未被索引器排序,如果给定 t_s 值多次出现(但选择的聚合是不可忽略的),或者存在 missing/skipped t_s(例如 t_s 1,2,3,4,5,7 的值)。它通常是非常强大的解决方案。