Отразить (развернуть) pandas.DataFrame
Есть pandas.DataFrame,в котором более 1000 уникальных имен и диапазон дат более месяца.
| Name | date | price | total_sales |
|---|---|---|---|
| Ручка | 2023-10-13 05:00:00 | 10 | 5 |
| Стол | 2023-10-13 05:00:00 | 15 | 1 |
| Ручка | 2023-10-16 07:00:00 | 11 | 3 |
| Стол | 2023-10-9 02:00:00 | 44 | 6 |
Его необходимо преобразовать в следующий вид:
| Name | series_type | 2023-10-9 02:00:00 | 2023-10-16 07:00:00 | 2023-10-13 05:00:00 |
|---|---|---|---|---|
| Ручка | price | nan | 11 | 10 |
| Ручка | total_sales | nan | 3 | 5 |
| Стол | price | 44 | nan | 15 |
| Стол | total_sales | 6 | nan | 1 |
Помогите, пожалуйста, написать функцию, которая сделает такое преобразование.
На данный момент я иду по следующему пути, но зашел в тупик:
def transpose_df(df):
# Нахожу все возможные даты которые передам в качестве названия колонок
start = df.date.min()
end = df.date.max()
total_hours = int((end-start).days * 24 + (end-start).seconds/60/60)
date_coll = [(start + timedelta(hours=x))
.strftime('%Y-%m-%d %H') for x in range(0, total_hours)]
# Создаю пустой df с необходимым типом колонок
df_new = pd.DataFrame(columns=[['name', 'series_type'] + date_coll],
dtype='datetime64[ns]')
df_new[['name', 'series_type']] = df_test[['name', 'series_type']].astype(object)
for nameDF in df.name.unique():
# Создаю два словаря
price_now = dict(
zip(list(map(str, df_analyze.date[df_analyze.name
== nameDF].tolist())),
df_analyze.price[df_analyze.name == nameDF]))
sales_now = dict(
zip(list(map(str, df_analyze.date[df_analyze.name
== nameDF].tolist())),
df_analyze.total_sales[df_analyze.name == nameDF]))
# Добавляю к ним
price_now.update({'name':nameDF, 'series_type':'prise'})
sales_now.update({'name':nameDF,
'series_type':'total_sales'})
df_new = df_new.append(price_now, ignore_index=True)
df_new = df_new.append(sales_now, ignore_index=True)
return df_new
Получаю ошибку
---> 22 df_new = df_new.append(price_now, ignore_index=True)
ValueError: no types given
Ответы (1 шт):
Автор решения: Kirill Kondratenko
→ Ссылка
Используй комбинацию melt и pivot:
import pandas as pd
df = pd.DataFrame({'Name': ['Ручка', 'Стол', 'Ручка', 'Стол'],
'date': ['2023-10-13 05:00:00', '2023-10-13 05:00:00',
'2023-10-16 07:00:00', '2023-10-9 02:00:00'],
'price': [10, 15, 11, 44],
'total_sales': [5, 1, 3, 6]})
def transpose_df(data):
df = data.melt(
id_vars=['Name', 'date'],
var_name='series_type').pivot(
index=['Name', 'series_type'],
columns='date', values='value').reset_index()
return df
print(transpose_df(df))
Вывод:
Name series_type 2023-10-13 05:00:00 2023-10-16 07:00:00 2023-10-9 02:00:00
0 Ручка price 10.0 11.0 NaN
1 Ручка total_sales 5.0 3.0 NaN
2 Стол price 15.0 NaN 44.0
3 Стол total_sales 1.0 NaN 6.0