Это один из способов использования collections.defaultdict
.
from collections import defaultdict
from operator import itemgetter
d = defaultdict(list)
for code, attr, rank in df.itertuples(index=False):
d[code].append((attr, rank))
d = {k: sorted(v, key=itemgetter(1), reverse=True)[:3] for k, v in d.items()}
res = pd.DataFrame(d).T.reset_index()
print(res)
index 0 1 2
0 394 (Feminine, 9) (Fresh, 9) (Heavy, 8)
1 418 (Soft, 13) (Fresh, 12) (Clean, 11)
2 539 (Fresh, 14) (Soft, 14) (Feminine, 11)
3 555 (Feminine, 9) (Heavy, 8) (Soft, 7)
Вы можете изменить имена столбцов и при необходимости предоставить дополнительное форматирование.На мой взгляд, лучше идея хранить кортежи, чем преобразовывать числовые данные в строки.
Если вам действительно нужно строковое представление ...
Вы можете использовать pd.Series.apply
:
for col in [0, 1, 2]:
res[col] = res[col].apply(lambda x: '{0} ({1})'.format(x[0], x[1]))