2 回答

TA贡献1801条经验 获得超8个赞
我的解决方案的想法基于具有范围定义的辅助 DataFrame,为此要计算平均值(上述属性的day_in_week、time_in_day 和相应的CustomBusinessHour )。
这个 DataFrame(我称之为calendars)的创建从 day_in_week , time_in_day列开始:
calendars = pd.DataFrame([
['sun', 'morning'],
['sun-thu', 'morning'],
['sun-thu', 'noon'],
['fri-sat', 'noon'],
['fri', 'eve']],
columns=['day_in_week', 'time_in_day'])
如果您需要更多此类定义,请在此处添加它们。
然后,添加相应的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 getWeekMask(name):
parts = name.split('-')
if len(parts) > 1:
fullWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
ind1 = fullWeek.index(parts[0].capitalize())
ind2 = fullWeek.index(parts[1].capitalize())
return ' '.join(fullWeek[ind1 : ind2 + 1])
else:
return parts[0].capitalize()
定义生成CustomBusinessHour对象的函数:
def getCBH(row):
wkMask = getWeekMask(row.day_in_week)
hStart, hEnd = getHourLimits(row.time_in_day)
return pd.offsets.CustomBusinessHour(weekmask=wkMask, start=hStart, end=hEnd)
将CustomBusinessHour对象添加到日历:
calendars['CBH'] = calendars.apply(getCBH, axis=1)
然后为给定的实体 Id 定义一个计算所有必需均值的函数:
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

TA贡献1839条经验 获得超15个赞
如果您的时间列是 pandas 中的日期时间对象,则可以使用数据时间方法创建新列,
您可以按照以下步骤操作,
您可以创建一个指示 day_in_week 的列,
df["day_in_week"] = df["time"].dt.dayofweek
然后使用一个简单的 .apply 函数根据您的要求制作列,通过比较函数内部的时间将时间划分为早上、晚上等时段。
然后根据之前创建的两列创建另一列指示您的组合。
然后在要获取该组的分组数据或指标的列上使用 groupby。
我知道这个过程有点长,但它没有任何 for 循环,它使用 pandas 已经提供的df.apply
和datetime
属性以及根据您的要求的一些 if-else 条件。
步骤 2、3、4 完全依赖于数据,因为我没有数据,所以我无法编写确切的代码。能用的方法我都尽量解释了。
我希望这有帮助。
添加回答
举报