Получить из одного dataframe другой

У меня есть датафрейм со столбцами id-имя-дата-оценка. Хочу из этого датафрейма получить другой, в котором становится больше столбцов благодаря столбцу даты. То есть хочу получить id-имя-оценка<дата>-оценка<дата>-оценка<дата>.

Вот моя попытка:


    dates = sorted(list(set(df[‘date’])))
    
    for scale in dates:
        for row in df.itertuples(): 
            if row.date == scale:
                df1[‘id1’] = df[‘id’]
                df1[‘name’] = df[‘name’]
                df1[‘value {}’.format(scale)] = df.value

Здесь пример таблиц as-is to-be введите сюда описание изображения


Ответы (2 шт):

Автор решения: Алексей Р

Сортируем фрейм по имени и дате, затем устанавливаем мультииндекс из идентификатора, времени и даты, после чего разворачиваем колонку value через unstack(). Возвращаем индексы в столбцы данных. Формируем названия колонок, склеивая их из кортежей мультииндекса колонок.

df = pd.DataFrame(
    {'id': [1, 2, 3, 1, 2, 3], 'name': ['anya', 'tiffany', 'mike', 'anya', 'tiffany', 'mike'], 'date': ['2023-08-01', '2023-08-01', '2023-08-01', '2023-08-08', '2023-08-08', '2023-08-08'], 'value': [5, 4, 3, 3, 4, 5]})
df = df.sort_values(['name', 'date']).set_index(['id', 'name', 'date']).unstack().reset_index()
df.columns = [f'{x} {y}'.strip() for x, y in df.columns]
print(df)
   id     name  value 2023-08-01  value 2023-08-08
0   1     anya                 5                 3
1   2  tiffany                 4                 4
2   3     mike                 3                 5
→ Ссылка
Автор решения: Kirill Kondratenko

Как вариант, можно пересобрать при помощи pivot():

df = pd.DataFrame(
        {'id': [1, 2, 3, 1, 2, 3],
         'name': ['anya', 'tiffany', 'mike', 'anya', 'tiffany', 'mike'],
         'date': ['2023-08-01', '2023-08-01', '2023-08-01', '2023-08-08', '2023-08-08', '2023-08-08'],
         'value': [5, 4, 3, 3, 4, 5]})
    
df['date'] = 'value ' + df['date'].astype(str) # убрать, если value в дате не нужен
df = pd.DataFrame(df.pivot(index=['id', 'name'],
                           columns='date',
                           values='value').to_records())
print(df)

   id     name  value 2023-08-01  value 2023-08-08
0   1     anya                 5                 3
1   2  tiffany                 4                 4
2   3     mike                 3                 5
→ Ссылка