我有一个包含每小时数据的数据框:
area date hour output
H1 2018-07-01 07:00:00 150
H1 2018-07-01 08:00:00 150
H1 2018-07-01 09:00:00 100
H1 2018-07-01 11:00:00 150
H2 2018-07-01 09:00:00 100
H2 2018-07-01 10:00:00 50
H2 2018-07-01 11:00:00 50
H2 2018-07-01 12:00:00 150
但是数据仅包含输出时数的行,如何为输出0的每个区域填写缺少的时数?例如,为H1添加两行:
area date hour output
H1 2018-07-01 10:00:00 0
H1 2018-07-01 12:00:00 0
我可以假设所有区域的最小和最大小时数是采样周期的开始和结束时间(在这种情况下为7:00:00和12:00:00)
现在,我正在创建一个数据框,其中包含每个区域从7:00到12:00的所有小时,然后将我的数据与该数据框合并,然后用0填充NaN。这非常慢,因为我的数据集可以包含数百万行。
还有更好的方法吗?
答案 0 :(得分:1)
您可以使用resample
来检查groupby
df['Datetime']=pd.to_datetime(df.date+' '+df.hour)# combine hour and date to datetime
df.drop(['date','hour'],inplace=True,axis = 1)# drop duplicate infomation
df.groupby('area').\
apply(lambda x : x.set_index('Datetime').resample('H').mean().fillna(0)).\
reset_index()
Out[662]:
area Datetime output
0 H1 2018-07-01 07:00:00 150.0
1 H1 2018-07-01 08:00:00 150.0
2 H1 2018-07-01 09:00:00 100.0
3 H1 2018-07-01 10:00:00 0.0
4 H1 2018-07-01 11:00:00 150.0
5 H2 2018-07-01 09:00:00 100.0
6 H2 2018-07-01 10:00:00 50.0
7 H2 2018-07-01 11:00:00 50.0
8 H2 2018-07-01 12:00:00 150.0
答案 1 :(得分:1)
您可以创建日期范围的最大值和最小值,并将数据框与现有数据合并,并使用null填充值
df
area date hour output
0 H1 2018-07-01 07:00:00 07:00:00 150
1 H1 2018-07-01 08:00:00 08:00:00 150
2 H1 2018-07-01 09:00:00 09:00:00 100
6 H2 2018-07-01 11:00:00 11:00:00 50
7 H2 2018-07-01 12:00:00 12:00:00 150
df = pd.DataFrame(pd.date_range(pd.to_datetime(df['date'] +' ' + df['hour']).min(),pd.to_datetime(df['date'] +' ' + df['hour']).max(),freq='H'),columns= ['date']).merge(df,on=['date'],how='outer').fillna(0)
df.hour = df.date.dt.strftime('%H:%M:%S')
df.date = df.date.dt.strftime('%d-%m-%Y')
df
出局:
date area hour output
0 01-07-2018 H1 07:00:00 150.0
1 01-07-2018 H1 08:00:00 150.0
2 01-07-2018 H1 09:00:00 100.0
3 01-07-2018 0 10:00:00 0.0
4 01-07-2018 H2 11:00:00 50.0
5 01-07-2018 H2 12:00:00 150.0
答案 2 :(得分:0)
Wen 提出的解决方案只要源日期/时间来自 单个测量日。
如果来源包含不同天的读数,则重新采样的结果 从第一天的最早阅读到最新 在最后一天阅读的内容,包括夜间时段,什么是 可能不是您想要的。
该解决方案的另一个缺点是它不提供“零”读数 从测量的一开始就开始,但是从最早的阅读开始。 同样适用于“最终”阅读,也不一定在末尾 测量日。
我的解决方案没有这些缺点,它基于以下假设:
下面有示例程序:
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
根据需要,提供3个区域/日期对的一系列7个读数。