У меня есть фрейм данных (namend df) с 01.01.2016 00:00 до 23:00 25.11.2018 с отметкой времени каждый час, object_id и значением. Набор данных содержит только строки, в которых object_id имеет значение.
timestampHour object_id value
2016/1/1 00:00 1 2
2016/1/1 00:00 3 1
2016/1/1 01:00 1 1
2016/1/1 01:00 2 3
2016/1/1 02:00 2 3
2016/1/1 02:00 3 2
Я хотел бы получить фрейм данных, показывающий все идентификаторы объекта за каждый час, с нулевым значением, если нет значения.
timestampHour object_id value
2016/1/1 00:00 1 2
2016/1/1 00:00 2 null
2016/1/1 00:00 3 1
2016/1/1 01:00 1 1
2016/1/1 01:00 2 3
2016/1/1 01:00 3 null
2016/1/1 02:00 1 null
2016/1/1 02:00 2 3
2016/1/1 02:00 3 2
Я создал dateTime из временных меток. И округлили их до часов с помощью следующего кода:
df["timestamp"] = pd.to_datetime(df["result_timestamp"])
df['timestampHour'] = df['result_timestamp'].dt.round('60min')
(Я не знаю, есть ли лучшие варианты, но я пытался создать строки timestampHour до 12 (у меня 12 каждого уникального object_id) и заполнить эти вновь созданные строки (на этот час) неиспользуемым object_id. Но у меня есть не удалось создать пустые строки с условием)
Я новичок в программировании, и я не нахожу подсказки, чтобы приблизиться к решению этой проблемы, просматривая другие сообщения.






Использование pivot_table и unstack:
df.pivot_table(
index='object_id', columns='timestampHour', values='value'
).unstack().rename('value').reset_index()
timestampHour object_id value
0 2016/1/1 00:00 1 2.0
1 2016/1/1 00:00 2 NaN
2 2016/1/1 00:00 3 1.0
3 2016/1/1 01:00 1 1.0
4 2016/1/1 01:00 2 3.0
5 2016/1/1 01:00 3 NaN
6 2016/1/1 02:00 1 NaN
7 2016/1/1 02:00 2 3.0
8 2016/1/1 02:00 3 2.0
Чтобы понять, почему это работает, полезно посмотреть на промежуточный pivot_table:
timestampHour 2016/1/1 00:00 2016/1/1 01:00 2016/1/1 02:00
object_id
1 2.0 1.0 NaN
2 NaN 3.0 3.0
3 1.0 NaN 2.0
Если значение не является найдено для комбинации object_id и timestampHour, в таблицу добавляется NaN. Когда вы используете unstack, эти NaN сохраняются, что дает вам желаемый результат с пропущенными значениями.
Это также .reindex с декартовым произведением двух уровней. Этот вопрос подробно описывает способы оптимизации производительности продукта для больших наборов данных.
import pandas as pd
id_cols = ['timestampHour', 'object_id']
idx = pd.MultiIndex.from_product(df[id_cols].apply(pd.Series.unique).values.T, names=id_cols)
df.set_index(id_cols).reindex(idx).reset_index()
timestampHour object_id value
0 2016/1/1 00:00 1 2.0
1 2016/1/1 00:00 3 1.0
2 2016/1/1 00:00 2 NaN
3 2016/1/1 01:00 1 1.0
4 2016/1/1 01:00 3 NaN
5 2016/1/1 01:00 2 3.0
6 2016/1/1 02:00 1 NaN
7 2016/1/1 02:00 3 2.0
8 2016/1/1 02:00 2 3.0