随着时间的推移计算建筑中的人数

时间:2018-11-27 14:35:34

标签: python pandas datetime

我正在努力寻找一种“简单”的方式来对熊猫进行这种分析:

我有xlsx文件,该文件显示了人们进入建筑物的过程。 在这里,我显示了原始数据的简化版本。

       Full Name                 Time Direction
0  Uncle Scrooge  08-10-2018 09:16:52        In
1  Uncle Scrooge  08-10-2018 16:42:40       Out
2    Donald Duck  08-10-2018 15:04:07        In
3    Donald Duck  08-10-2018 15:06:42       Out
4    Donald Duck  08-10-2018 15:15:49        In
5    Donald Duck  08-10-2018 16:07:57       Out

我理想的最终结果是以表格或更好的图形方式显示建筑物总人数随时间变化的情况。 所以回到我提供的示例数据,我想证明一下在2018年8月10日这一天:

  • 09:16:52之前没有人进入建筑物
  • 从09:16:52到15:04:06那里有1个人(史克鲁奇叔叔)
  • 从15:04:07到15:06:42有2个人(史克鲁奇叔叔和唐老鸭)
  • 从15:06:42到15:15:48有1个人
  • 从15:15:49到16:07:57又有2个
  • 从16:07:58到16:42:40又有1个
  • 从16:42:41到一天结束时

在该示例中,我使用了真实数据,因此您可以看到时间戳精确到秒,但是我并不需要那么精确,因为该分析必须在2个月的范围内进行。

感谢您的帮助

非常感谢

乔治

================ 更新:===============

@nixon和@ALollz非常感谢您。 它非常完美,除了我最初提出的问题中没有想到的细节。

事实上,正如我所提到的,我正在处理两个月的数据。 而且,由于某种原因,似乎并不是所有进入建筑物的人在离开建筑物时都被追踪到。 因此,使用cumsum()函数,我发现一天中的总人数受到前一天的人们的影响,依此类推, 这表明,除了最初的几天外,在每天的清晨和傍晚都有大量人员进入该建筑物。

因此,我认为可以通过先在几天内执行group_by然后应用您的建议来解决此问题。

您能帮我把一切放在一起吗? 非常感谢

乔治

1 个答案:

答案 0 :(得分:0)

您可以首先将Time列设置为索引,然后使用sort_index对其进行排序:

df = df.set_index('Time').sort_index()
print(df)

                Direction      Full Name
Time                                        
2018-08-10 09:16:52        In  Uncle Scrooge
2018-08-10 15:04:07        In    Donald Duck
2018-08-10 15:06:42       Out    Donald Duck
2018-08-10 15:15:49        In    Donald Duck
2018-08-10 16:07:57       Out    Donald Duck
2018-08-10 16:42:40       Out  Uncle Scrooge

并创建{'In':1, 'Out':-1}的映射(如@ALollz建议):

mapper = {'In':1, 'Out':-1}
df = df.assign(Direction_mapped = df.Direction.map(mapper))

哪个会给你:

                   Direction      Full Name  Direction_mapped
Time                                                          
2018-08-10 09:16:52        In  Uncle Scrooge                 1
2018-08-10 15:04:07        In    Donald Duck                 1
2018-08-10 15:06:42       Out    Donald Duck                -1
2018-08-10 15:15:49        In    Donald Duck                 1
2018-08-10 16:07:57       Out    Donald Duck                -1
2018-08-10 16:42:40       Out  Uncle Scrooge                -1

已经映射了“方向”列,您可以简单地将cumsum应用于结果,这将为您提供从特定时间开始的人数:

df = df.assign(n_people = df.Direction_mapped.cumsum()).drop(['Direction_mapped'], axis = 1)

哪种产量:

                       Direction  Full Name  n_people
Time                                                  
2018-08-10 09:16:52        In  Uncle Scrooge         1
2018-08-10 15:04:07        In    Donald Duck         2
2018-08-10 15:06:42       Out    Donald Duck         1
2018-08-10 15:15:49        In    Donald Duck         2
2018-08-10 16:07:57       Out    Donald Duck         1
2018-08-10 16:42:40       Out  Uncle Scrooge         0

常规解决方案

针对并非所有人都被跟踪离开建筑物的情况的更通用解决方案。让我们尝试一个包含多于一天的新df。还让我们模拟这次唐纳德·达克(Donald Duck)确实进过两次,但是第二次却没有被跟踪到进去。

df = pd.DataFrame({'Full Name': ['Uncle Scrooge','Uncle Scrooge', 'Donald Duck', 'Donald Duck', 'Donald Duck',
                                 'Someone else', 'Someone else'],
                   'Time': ['08-10-2018 09:16:52','08-10-2018 16:42:40', '08-10-2018 15:04:07', '08-10-2018 15:06:42', '08-10-2018 15:15:49', 
                            '08-11-2018 10:42:40', '08-11-2018 10:48:40'],
                  'Direction': ['In','Out','In','Out', 'In','In', 'Out']})
print(df)

     Full Name          Time               Direction
0  Uncle Scrooge  08-10-2018 09:16:52        In
1  Uncle Scrooge  08-10-2018 16:42:40       Out
2    Donald Duck  08-10-2018 15:04:07        In
3    Donald Duck  08-10-2018 15:06:42       Out
4    Donald Duck  08-10-2018 15:15:49        In
5   Someone else  08-11-2018 10:42:40        In
6   Someone else  08-11-2018 10:48:40       Out

首先,可以将先前的功能封装在一个函数中

def apply_by_day(x):
    mapper = {'In':1, 'Out':-1}
    x = x.assign(Direction_mapped = x.Direction.map(mapper))
    x = x.assign(n_people = x.Direction_mapped.cumsum())\
         .drop(['Direction_mapped'], axis = 1)
    return x

然后可以使用pandas.Grouperapply_by_day应用于日常组:

df.Time = pd.to_datetime(df.Time)
df = df.set_index('Time').sort_index()
df.groupby(pd.Grouper(freq='D')).apply(lambda x: apply_by_day(x))

                                 Full Name       Direction  n_people
Time       Time                                                  
2018-08-10 2018-08-10 09:16:52  Uncle Scrooge        In         1
           2018-08-10 15:04:07    Donald Duck        In         2
           2018-08-10 15:06:42    Donald Duck       Out         1
           2018-08-10 15:15:49    Donald Duck        In         2
           2018-08-10 16:42:40  Uncle Scrooge       Out         1
2018-08-11 2018-08-11 10:42:40   Someone else        In         1
           2018-08-11 10:48:40   Someone else       Out         0

如结果数据框所示,即使没有被追踪到2018-08-10离开建筑物,n_people仍会在第二天从0开始,因为每天分别应用定义的功能。