Python在不同的日期和日期范围内重新采样特定的小时数
我有不同实体的数据记录,每个实体在一天中的某个特定时间内记录了整整一个月的计数。 例如:Python在不同的日期和日期范围内重新采样特定的小时数,python,pandas,Python,Pandas,我有不同实体的数据记录,每个实体在一天中的某个特定时间内记录了整整一个月的计数。 例如: entity_id time counts 0 175 2019-03-01 05:00:00 3 1 175 2019-03-01 06:00:00 4 2 175 2019-03-01 07:00:00 6 3 175 2019-03-01 08:00:00 6 4
entity_id time counts
0 175 2019-03-01 05:00:00 3
1 175 2019-03-01 06:00:00 4
2 175 2019-03-01 07:00:00 6
3 175 2019-03-01 08:00:00 6
4 175 2019-03-01 09:00:00 7
5 178 2019-03-01 05:00:00 8
6 178 2019-03-01 06:00:00 4
7 178 2019-03-01 07:00:00 5
8 178 2019-03-01 08:00:00 6
9 200 2019-03-01 05:00:00 7
10 200 2019-03-01 08:00:00 3
11 175 2019-03-03 05:00:00 3
12 175 2019-03-03 07:00:00 6
13 175 2019-03-03 08:00:00 6
14 175 2019-03-03 09:00:00 7
15 178 2019-03-03 05:00:00 8
16 178 2019-03-03 06:00:00 4
17 178 2019-03-03 07:00:00 5
18 178 2019-03-03 08:00:00 6
19 200 2019-03-03 05:00:00 7
20 200 2019-03-03 08:00:00 3
21 200 2019-03-03 09:00:00 7
...
我希望能够为每个实体汇总整个月内一周中不同天数内几个小时范围内的计数平均值。例如:
- 周日上午(6-10点)的平均值
- 星期日和星期四上午(6-10点)的平均值
- 周日至周四中午(上午11点至下午1点)的平均值
- 周五至周六中午(上午11点至下午1点)的平均值
- 周五晚上(下午6点至9点)的平均值
- 等等
我开始的时候是,但是我仍然有太多的for循环。您知道如何优化性能吗?如果您的时间列是pandas中的datetime对象,您可以使用datatime方法创建新列 您可以按照以下步骤操作
df[“周中的天”]=df[“时间”].dt.dayofweek
df.apply
和datetime
属性,以及根据您的要求提供的一些if-else条件
步骤2、3、4完全依赖于数据,因为我没有数据,所以无法编写准确的代码。我尽力解释可以使用的方法
我希望这有帮助。如果您的时间列是pandas中的datetime对象,您可以使用datatime方法创建新列 您可以按照以下步骤操作
df[“周中的天”]=df[“时间”].dt.dayofweek
df.apply
和datetime
属性,以及根据您的要求提供的一些if-else条件
步骤2、3、4完全依赖于数据,因为我没有数据,所以无法编写准确的代码。我尽力解释可以使用的方法
我希望这能有所帮助。我的解决方案是基于一个带有定义的辅助数据框 要计算其平均值的范围(周中的天、日中的时间) 以及上述属性的相应CustomBusinessHour) 这个数据框架(我称之为日历)的创建从 周中的日、日列中的时间: 如果您想要更多这样的定义,请在此处添加它们 然后,要添加相应的CustomBusinessHour对象:
def getHourLimits(name):
if name == 'morning':
return '06:00', '10:00'
elif name == 'noon':
return '11:00', '13:00'
elif name == 'eve':
return '18:00', '21:00'
else:
return '8:00', '16:00'
def getSums(entId):
outRows = []
wrk = df[df.entity_id.eq(entId)] # Filter for entity Id
for _, row in calendars.iterrows():
dd = row.day_in_week
hh = row.time_in_day
cbh = row.CBH
# Filter for the current calendar
cnts = wrk[wrk.time.apply(lambda val: cbh.is_on_offset(val))]
cnt = cnts.counts.mean()
if pd.notnull(cnt):
outRows.append(pd.Series([entId, dd, hh, cnt],
index=['entity_id', 'day_in_week', 'time_in_day', 'counts_mean']))
return pd.DataFrame(outRows)
如您所见,结果只包含非空的平均值
要生成结果,请运行:
pd.concat([getSums(entId) for entId in df.entity_id.unique()], ignore_index=True)
对于您的数据样本(仅包含早晨的读数),
结果是:
entity_id day_in_week time_in_day counts_mean
0 175 sun morning 6.333333
1 175 sun-thu morning 6.333333
2 178 sun morning 5.000000
3 178 sun-thu morning 5.000000
4 200 sun morning 5.000000
5 200 sun-thu morning 5.000000
我的解决方案的思想是基于一个带有定义的辅助数据帧 要计算其平均值的范围(周中的天、日中的时间) 以及上述属性的相应CustomBusinessHour) 这个数据框架(我称之为日历)的创建从 周中的日、日列中的时间: 如果您想要更多这样的定义,请在此处添加它们 然后,要添加相应的CustomBusinessHour对象:
def getHourLimits(name):
if name == 'morning':
return '06:00', '10:00'
elif name == 'noon':
return '11:00', '13:00'
elif name == 'eve':
return '18:00', '21:00'
else:
return '8:00', '16:00'
def getSums(entId):
outRows = []
wrk = df[df.entity_id.eq(entId)] # Filter for entity Id
for _, row in calendars.iterrows():
dd = row.day_in_week
hh = row.time_in_day
cbh = row.CBH
# Filter for the current calendar
cnts = wrk[wrk.time.apply(lambda val: cbh.is_on_offset(val))]
cnt = cnts.counts.mean()
if pd.notnull(cnt):
outRows.append(pd.Series([entId, dd, hh, cnt],
index=['entity_id', 'day_in_week', 'time_in_day', 'counts_mean']))
return pd.DataFrame(outRows)
如您所见,结果只包含非空的平均值
要生成结果,请运行:
pd.concat([getSums(entId) for entId in df.entity_id.unique()], ignore_index=True)
对于您的数据样本(仅包含早晨的读数),
结果是:
entity_id day_in_week time_in_day counts_mean
0 175 sun morning 6.333333
1 175 sun-thu morning 6.333333
2 178 sun morning 5.000000
3 178 sun-thu morning 5.000000
4 200 sun morning 5.000000
5 200 sun-thu morning 5.000000
我会试一试:)如果我按照第3步做,那么我会得到一个列:“3_morning”“0_morning”等等。假设他们我想将这两行分为3次:第0天一次,第3天一次,两天一次-我如何在groupby中表达这一点?这会有帮助!我会试一试:)如果我按照第3步做,那么我会得到一个列:“3_morning”“0_morning”等等。假设他们我想将这两行分为3次:第0天一次,第3天一次,两天一次-我如何在groupby中表达这一点?这会有帮助!
entity_id day_in_week time_in_day counts_mean
0 175 sun morning 6.333333
1 175 sun-thu morning 6.333333
2 178 sun morning 5.000000
3 178 sun-thu morning 5.000000
4 200 sun morning 5.000000
5 200 sun-thu morning 5.000000