Подсчет количества людей в строительстве с течением времени - PullRequest
0 голосов
/ 27 ноября 2018

Я изо всех сил пытаюсь найти «простой» способ выполнить этот анализ с помощью Pandas:

У меня есть файлы 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

Мой идеальный конечный результат - показать (в табличной или более качественной графической форме), как общее количество людей в здании меняется с течением времени.Итак, возвращаясь к приведенным мной образцам данных, я хотел бы показать, что в течение дня 08-10-2018:

  • до 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 спасибо большое, ты потрясающий.Это работает отлично, за исключением деталей, о которых я не думаю в своем первоначальном вопросе.

Фактически, как я уже упоминал, я работаю с данными, охватывающими период в 2 месяца.Более того, по некоторым причинам кажется, что не все люди, входящие в здание, были отслежены при выходе из него.Таким образом, с помощью функции cumsum () я нахожу общее количество людей в течение дня, на которые оказали влияние люди предыдущего дня и т. Д. Это показывает неоправданно большое количество людей в здании в ранние и поздние часы любых дней.кроме самых первых.

Так что я подумал, что это можно решить, выполнив сначала group_by по дням, а затем применив ваше предложение.

Не могли бы вы помочь мне собрать все вместе?Большое спасибо

Джорджио

1 Ответ

0 голосов
/ 27 ноября 2018

Вы можете начать с установки столбца 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

И создать отображение (как предлагает @ALollz){'In':1, 'Out':-1}:

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, который включает в себя более одного дня.Также давайте смоделируем на этот раз, что Дональд Дак входит дважды, но не отслеживается, выходя во второй раз:

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

И затем apply_by_day можно применить к ежедневным группам, используя pandas.Grouper:

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 на следующий день, так как определенная функция применяется для каждого дня отдельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...