Решение, предложенное Вен , работает, пока даты / время источника взяты из одного дня измерения.
Если источник содержал показания из в разное дней, результат повторная выборка для каждой области будет от самого раннего чтения в первый день до самого последнего чтения в последний день , включая промежуточные ночные часы , что, вероятно, не то, что вам нужно.
Еще один недостаток этого решения заключается в том, что оно не обеспечивает «нулевые» показания с самого начала дня измерения, а с самого раннего считывания.То же самое относится к «окончательному» чтению, также не обязательно в конце дня измерения.
Мое решение, свободное от этих недостатков, основано на следующих предположениях:
- Оставьте исходный столбец date , так как он понадобится позже.После вычисления Datetime только столбец сброса hour .
- Generate df_borders DataFrame, содержащий NaN показания для начала / концадня измерения, для каждой области и даты, я предположил для 07: 00: 00 и 13: 00: 00 .
- Добавить вышеуказанное NaN показания на основной DataFrame и удаление дубликатов для каждой области / DateTime .Таким образом, исходные данные для каждой области / дня содержат показания для точного начала / конца каждого дня, либо оригинальные, либо добавленные из df_borders .
- Чтобы избежать "не рабочего дняmsgstr "чтения, группировка должна выполняться на ['area', 'date'] .Вот почему я оставил столбец date до сих пор.
- Теперь столбец date не нужен и его можно удалить.
- Последний шаг -распечатать результат.
Ниже приведен пример программы:
import pandas as pd
df = pd.read_csv('Input.csv')
# Generate df_borders - NaN readings for start / end of each area / date
df_start = df[['area','date']].drop_duplicates()
df_end = df_start.copy()
df_start['hour'] = '07:00:00'
df_end['hour'] = '13:00:00'
df_borders = pd.concat([df_start,df_end])
# Compute Datetime column and drop hour column, for both DataFrames
df['Datetime'] = pd.to_datetime(df.date + ' ' + df.hour)
df.drop('hour', inplace=True, axis = 1)
df_borders['Datetime'] = pd.to_datetime(df_borders.date + ' ' + df_borders.hour)
df_borders.drop('hour', inplace=True, axis = 1)
# Add NaN readings
df = df.append(df_borders, sort=False, ignore_index=True)\
.drop_duplicates(subset=['area', 'Datetime'])
# Generate the full set of readings
df = df.groupby(['area', 'date'])\
.apply(lambda x : x.set_index('Datetime').resample('H').mean().fillna(0))\
.reset_index()
df.drop('date', inplace=True, axis = 1)
# Result
print(df)
Некоторые части являются копией решения Wen , чтобы избежать повторного изобретенияколесо.
Для исходных данных:
area,date,hour,output
H1,2018-07-01,07:00:00,150
H1,2018-07-01,08:00:00,120
H1,2018-07-01,09:00:00,90
H1,2018-07-01,11:00:00,130
H2,2018-07-01,09:00:00,110
H2,2018-07-01,10:00:00,50
H2,2018-07-01,11:00:00,80
H2,2018-07-01,12:00:00,110
H2,2018-07-02,08:00:00,40
H2,2018-07-02,09:00:00,65
H2,2018-07-02,11:00:00,95
H2,2018-07-02,12:00:00,45
он печатает:
area Datetime output
0 H1 2018-07-01 07:00:00 150.0
1 H1 2018-07-01 08:00:00 120.0
2 H1 2018-07-01 09:00:00 90.0
3 H1 2018-07-01 10:00:00 0.0
4 H1 2018-07-01 11:00:00 130.0
5 H1 2018-07-01 12:00:00 0.0
6 H1 2018-07-01 13:00:00 0.0
7 H2 2018-07-01 07:00:00 0.0
8 H2 2018-07-01 08:00:00 0.0
9 H2 2018-07-01 09:00:00 110.0
10 H2 2018-07-01 10:00:00 50.0
11 H2 2018-07-01 11:00:00 80.0
12 H2 2018-07-01 12:00:00 110.0
13 H2 2018-07-01 13:00:00 0.0
14 H2 2018-07-02 07:00:00 0.0
15 H2 2018-07-02 08:00:00 40.0
16 H2 2018-07-02 09:00:00 65.0
17 H2 2018-07-02 10:00:00 0.0
18 H2 2018-07-02 11:00:00 95.0
19 H2 2018-07-02 12:00:00 45.0
20 H2 2018-07-02 13:00:00 0.0
При необходимости, серия из 7 показаний, для 3 пар зона / дата.