每小时如何找到占用率?

时间:2019-06-22 19:23:05

标签: python pandas datetime aggregate

我试图显示在给定时间内有多少人在健身房。

已向我提供了登录数据,并希望显示每小时的占用情况,如下所示:

post_install do |installer|
        installer.pods_project.targets.each do |target|
            target.build_configurations.each do |config|
                config.build_settings['CLANG_WARN_DOCUMENTATION_COMMENTS'] = 'NO'
            end
        end
    end

登录信息是这样提供的:(PS我假设人们现在在那里花了大约1.5个小时,大约有100,000行。)

Date/Time | Occupants
1/1/2018 7:00AM | 4
1/1/2018 8:00AM | 12
1/1/2018 9:00AM | 16
1/1/2018 10:00AM | 13
1/1/2018 11:00AM | 11

将数据汇总到每小时中的一种好方法是什么?感谢任何人都能提供的帮助。

谢谢

4 个答案:

答案 0 :(得分:0)

您只是在寻求聚合方面的帮助吗?

您可以使用groupby进行计数。

In = df['Sign In'].groupby([df['Sign In'].apply(lambda x: x.strftime('%B %d, %Y, %H'))]).count()
Out = df['Sign In'].groupby([df['Sign Out'].apply(lambda x: x.strftime('%B %d, %Y, %H'))]).count()

Sign In
January 01, 2018, 09    1
January 01, 2018, 10    5
January 01, 2018, 11    5
Name: Sign In, dtype: int64
Sign Out
January 01, 2018, 10    1
January 01, 2018, 11    3
January 01, 2018, 12    3
January 01, 2018, 13    4
Name: Sign In, dtype: int64

然后您可以从此处开始重命名列,应用逻辑(即,这只是当前的增量)并进行合并以将框架连接在一起。

答案 1 :(得分:0)

您只需添加Sign In时有多少人(在我们的示例中为1)。然后用1.5H resample

df['people'] = 1
df.set_index(['Sign In']).resample('1.5H').count()

输出:

                    people
Sign In 
2018-01-01 09:00:00 4
2018-01-01 10:30:00 7

答案 2 :(得分:0)

这是我的镜头

import pandas as pd
from datetime import datetime

# convert to the right type
data['Sign In ']= data['Sign In '].apply(lambda x: datetime.strptime(x, '%d/%m/%y %I:%M %p '))

data[' Sign Out']= data[' Sign Out'].apply(lambda x: datetime.strptime(x, ' %d/%m/%y %I:%M %p'))

# save in and Out 
signin= pd.to_datetime(data['Sign In '])
signout= pd.to_datetime(data[' Sign Out'])

# in groupby you could add [signin.dt.date, signin.dt.hour] if necessary
In = data.groupby([signin.dt.hour]).count().drop(' Sign Out', axis=1)  

Out= data.groupby([signout.dt.hour]).count().drop('Sign In ', axis=1) 

In.index.rename('time', inplace=True)
Out.index.rename('time', inplace=True)

# concatenate in data 
data = pd.concat([In, Out], axis=1).fillna(0)
data['occupancy'] = (data['Sign In '] - data[' Sign Out']).cumsum()

输出

print(data) 

      Sign In    Sign Out  occupancy
time                                
9          1.0        0.0        1.0
10         5.0        1.0        5.0
11         5.0        3.0        7.0
12         0.0        3.0        4.0
13         0.0        4.0        0.0

答案 3 :(得分:0)

我的解决方案还适用于存在时间不是1.5小时的数据, 但日期必须是单日(根据您的组装方式) 您的样本数据)。

我将您的数据读取为固定宽度字段,并转换为 datetime

df = pd.read_fwf(pd.compat.StringIO(txt), colspecs=[(0, 15), (18, 33)],
    names=['Sign In', 'Sign Out'], parse_dates=[0, 1])

所以从一开始我就有适当的数据类型(不需要额外的调用 pd.to_datetime )。

第一步是创建一个 IntervalIndex

intervals = pd.IntervalIndex.from_arrays(df['Sign In'], df['Sign Out'], closed='left')

下一步是创建 hrs -完整时间列表:

hrs = pd.date_range(df['Sign In'].min(),
    df['Sign Out'].max() + pd.Timedelta('1H'), freq='H')

请注意,我为 max 值增加了1个小时,以使 大家出来后的“最后”小时。 就像 0 占用的最后一个小时一样,例如 CHAMI 。 如果不需要,只需删除这额外的一小时。

但是我们需要一个系列,同时将索引和值设置为这些小时,所以 我还创建了 hours

hours = pd.Series(hrs, index=hrs)

有了这些数据,可以在 单条说明:

occupancy = hours.apply(lambda hr: np.count_nonzero(
    intervals.map(lambda it: hr in it)))

结果是:

2018-01-01 09:00:00    1
2018-01-01 10:00:00    1
2018-01-01 11:00:00    5
2018-01-01 12:00:00    6
2018-01-01 13:00:00    4
2018-01-01 14:00:00    0
Freq: H, dtype: int64

值得与其他答案进行一些比较:

  • CHAMI 的答案具有 float 类型的数据(应为 int )。
  • CHAMI 解决方案在10:00的占用率显示为 5 ,而此时 时间实际上只有 1 个人在场。客户2至6 稍后(之后 10:00之后)登录。
  • 他的解决方案中10:00及以后时间的结果被“转移” 1小时之内。
  • 在列名中包含前导/尾随空格是个坏习惯 (就像 CHAMI 一样)。
  • krewsider 实际上仅显示登录/退出事件汇总, 但没有入住。
  • harvpan 走了 1.5 小时(为什么?)。另一个细节是他 显示 9:00 的入住率为 4 (为什么?),到目前为止,他的结果是 不完整。

还要注意一个不同之处, CHAMI 11:00 处显示 7 位。 (实际上是在 12:00 ),但我显示了 6 。 原因是我假设如果5号人在 12:00 离开, 因此,此时他已经不在

如果您想把这样的人当成仍然在场,请更改关闭 IntervalIndex 的属性设置为'both'并为您的数据提供结果 在 12:00 会是 7