我似乎无法正确地做到这一点...这是我想做的事情:
import pandas as pd
df = pd.DataFrame({
'item_id': [1,1,3,3,3],
'contributor_id': [1,2,1,4,5],
'contributor_role': ['sing', 'laugh', 'laugh', 'sing', 'sing'],
'metric_1': [80, 90, 100, 92, 50],
'metric_2': [180, 190, 200, 192, 150]
})
--->
item_id contributor_id contributor_role metric_1 metric_2
0 1 1 sing 80 180
1 1 2 laugh 90 190
2 3 1 laugh 100 200
3 3 4 sing 92 192
4 3 5 sing 50 150
我想将其重塑为:
item_id SING_1_contributor_id SING_1_metric_1 SING_1_metric_2 SING_2_contributor_id SING_2_metric_1 SING_2_metric_2 ... LAUGH_1_contributor_id LAUGH_1_metric_1 LAUGH_1_metric_2 ... <LAUGH_2_...>
0 1 1 80 180 N/A N/A N/A ... 2 90 190 ... N/A..
1 3 4 92 192 5 50 150 ... 1 100 200 ... N/A..
基本上,对于每个item_id,我都希望将所有相关数据收集到一行中。每个项目可能有多种类型的贡献者,每种类型都有一个最大值(例如,每个项目的最大SING贡献者= A,每个项目的最大LAUGH贡献者= B)。每个贡献者都有一组度量标准(但是对于同一贡献者,不同项目/贡献者类型的值可能不同)。
我可能可以通过一些看似低效的方法(例如,循环和匹配然后填充模板df)来实现这一目标,但是我想知道是否存在更有效的方法,可能是通过巧妙地指定index
/ values
/ columns
进行数据透视操作(或其他任何方法)。
提前感谢您的任何建议!
编辑:
最终将下面的Ben脚本修改为以下内容:
df['role_count'] = df.groupby(['item_id', 'contributor_role']).cumcount().add(1).astype(str)
df['contributor_role'] = df.apply(lambda row: row['contributor_role'] + '_' + row['role_count'], axis=1)
df = df.set_index(['item_id','contributor_role']).unstack()
df.columns = ['_'.join(x) for x in df.columns.values]
答案 0 :(得分:2)
您可以使用cumcount
创建附加密钥,然后执行unstack
df['newkey']=df.groupby('item_id').cumcount().add(1).astype(str)
df['contributor_id']=df['contributor_id'].astype(str)
s = df.set_index(['item_id','newkey']).unstack().sort_index(level=1,axis=1)
s.columns=s.columns.map('_'.join)
s
Out[38]:
contributor_id_1 contributor_role_1 ... metric_1_3 metric_2_3
item_id ...
1 1 sing ... NaN NaN
3 1 messaround ... 50.0 150.0