Если отметка времени в одной таблице находится между двумя отметками времени в другой таблице, то увеличьте на 1, используя Python Pandas - PullRequest
0 голосов
/ 25 мая 2020

Краткое изложение проблемы:

Я хотел бы подсчитать количество машин скорой помощи при ответе в любую минуту дня в течение всего календарного года. Генерируются два pandas фреймов данных; Первый - это экстренное реагирование машин скорой помощи, показывающее отметку времени начала экстренной ситуации и отметку времени окончания этой экстренной помощи. Эти данные поступают из нашей базы данных. Например, скорая помощь отреагировала на арест cardia c в 2020-01-01 00:30:17, а скорая помощь была исключена из этого ответа в 2020-01-01 00: 38: 05.000. Назовем этот фрейм данных «аварийное_событие».

Второй pandas фрейм данных принимает минимальное значение Emergency_event и максимальное значение. Он генерирует фрейм данных, используя минимальные и максимальные временные метки в качестве начальной и конечной точек другого фрейма данных. Он увеличивается на одну минуту от начальной точки до конечной точки и генерирует ноль в качестве заполнителя для количества работающих грузовиков. Назовем этот второй фрейм данных «совпадающим», потому что мы хотим подсчитать количество машин скорой помощи, работающих по совпадению в течение этого одноминутного временного интервала.

Другими словами, первое аварийное событие началось в «2020-01-01 00: 00:28 ", поэтому таблица" совпадающих "событий примет это значение и увеличится на одну минуту до самой последней отметки времени окончания Emergency_event. Например, «совпадающая» таблица будет выглядеть так:

calendar_timestamp      TrucksWorking

2020-01-01 00:00:28              0

2020-01-01 00:01:28              0

2020-01-01 00:02:28              0

2020-01-01 00:03:28              0

2020-01-01 00:04:28              0

2020-01-01 00:05:28              0

......

Обратите внимание, как она увеличивается на одну минуту и ​​есть нулевой заполнитель для количества работающих машин скорой помощи.

Сейчас есть два фрейма данных: «Emergency_event» и «совпадающая» таблица. Цель программы - использовать первое наблюдение таблицы «совпадений» и выполнить оценку по каждой строке таблицы «Emergency_events». Имеется ли отметка времени «совпадающего» наблюдения между StartTime и EndTime «Emergency_events»? Если True, то увеличивайте значение TrucksWorking на 1. L oop через каждое «совпадающее» наблюдение и оцените, находится ли он между любым из «чрезвычайных_событий», и увеличьте на 1, если истина.

В конце программы это сгенерирует фрейм данных с приращением в одну минуту и ​​количество машин скорой помощи, работающих в это время. Используя эти данные, я могу статистически проанализировать количество машин скорой помощи, работающих в любой момент времени, и даже проанализировать его по часам дня, будням, дневным / ночным дням и т. Д. c. Это очень важная информация.

Но я застрял на логи c, и мне нужна ваша помощь. В частности, я не могу понять, как заставить "совпадающую" таблицу добавить 1, когда ее временная метка находится в таблице "Emergency_events".

То, что я пробовал

for each in coincident.calendar_timestamp:
    if (coincident[coincident['calendar_timestamp']] >= emergency_events[emergency_events['StartTime']] & coincident[coincident['calendar_timestamp']] <= emergency_events[emergency_events['EndTime']]):
        coincident[coincident['TrucksWorking']] = coincident[coincident['TrucksWorking']] + 1
    else:
        coincident[coincident['TrucksWorking']]

Я также пытался:

# =============================================================================
# I have attempted the following
# the following code returns an error message
# ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
# =============================================================================
## for each in coincident.calendar_timestamp:
##     if (coincident[coincident['calendar_timestamp'].between(starting_point, ending_point)]):
##         coincident[coincident['TrucksWorking']] = coincident[coincident['TrucksWorking']] + 1
##     else:
##         coincident[coincident['TrucksWorking']]

# =============================================================================
# I have attempted the following
# a dead end code that I cannot make work
# df = coincident[coincident['calendar_timestamp'].between(starting_point, ending_point)]
# print(df.head(n = 5))
# =============================================================================

# =============================================================================
# I have attempted the following but it will not work
# another dead end code
# for timestamp in coincident_events.calendar:
#     print(coincident_events.calendar.query('coincident_events.calendar >= emergency_events.starting_point and coincident_events.calendar <= emergency_events.ending_point'))
# =============================================================================

Показать мой код:

# -*- coding: utf-8 -*-
# Python 3.7 Anaconda distribution
import pandas as pd
import datetime

# =============================================================================
# Step 1: Read in the ambulance runs with a starting and ending time values
# call this dataframe "emergency_events"
# =============================================================================

# the following array is a small sample when an ambulance starts a call and when it ends a call
data = [['2020-01-01 00:00:28.000','2020-01-01 00:35:28.987']
        , ['2020-01-01 00:02:34.000','2020-01-01 01:05:13.540']
        , ['2020-01-01 00:03:57.000','2020-01-01 01:14:44.537']
        , ['2020-01-01 00:06:17.000','2020-01-01 01:26:52.087']
        , ['2020-01-01 00:13:20.000','2020-01-01 01:17:31.310']
        , ['2020-01-01 00:14:01.000','2020-01-01 01:57:28.343']
        , ['2020-01-01 00:16:11.000','2020-01-01 00:39:34.967']
        , ['2020-01-01 00:22:03.000','2020-01-01 01:46:40.037']
        , ['2020-01-01 00:23:07.000','2020-01-01 00:49:25.890']
        , ['2020-01-01 00:23:19.000','2020-01-01 01:26:39.920']
        , ['2020-01-01 00:30:17.000','2020-01-01 00:38:05.000']] 

#convert the array to a pandas data frame
emergency_events = pd.DataFrame(data, columns = ['StartTime', 'EndTime'])

#convert the string values to date time values
emergency_events['StartTime'] = pd.to_datetime(emergency_events['StartTime'])
emergency_events['EndTime'] = pd.to_datetime(emergency_events['EndTime'])

# =============================================================================
# Step 2 Create a calendar of date time stamps incremented by 1 minute using the ambulance runs min/max values
# call this dataframe "coincident"
# =============================================================================

## establish a starting value based on the first ambulance event
starting_point = emergency_events.StartTime.min()
print(starting_point)
## establish an ending value based on the final ambulance call ending time.
ending_point = emergency_events.EndTime.max()
print(ending_point)
## create a range of time stamps incremented by 1 minute from starting point to ending point
days = pd.date_range(starting_point, ending_point, freq='min')

## create a pandas dataframe with two columns: calendar for time stamps and a place holder of 0 for trucks working 
coincident = pd.DataFrame({'calendar_timestamp': days, 'TrucksWorking': 0})
## print it out to verify the data
print(coincident.head(n = 5))

# =============================================================================
# Step 3 --- now for the difficult part
# if a "coincident" time stamp is between a start and end time of an emergency_event
# increment the TrucksWorking column by 1
# loop through every "coincident" observation and test if it is between a start and an end of an "emergency_event"
# =============================================================================
for each in coincident.calendar_timestamp:
    if (coincident[coincident['calendar_timestamp']] >= emergency_events[emergency_events['StartTime']] & coincident[coincident['calendar_timestamp']] <= emergency_events[emergency_events['EndTime']]):
        coincident[coincident['TrucksWorking']] = coincident[coincident['TrucksWorking']] + 1
    else:
        coincident[coincident['TrucksWorking']]

## at the end of this program it should return a calendar of date time stamps with 
## the number of ambulances at work during that one minute interval.
## this information can be used for data modeling.

# =============================================================================
# I have attempted the following
# the following code returns an error message
# ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
# =============================================================================
## for each in coincident.calendar_timestamp:
##     if (coincident[coincident['calendar_timestamp'].between(starting_point, ending_point)]):
##         coincident[coincident['TrucksWorking']] = coincident[coincident['TrucksWorking']] + 1
##     else:
##         coincident[coincident['TrucksWorking']]

# =============================================================================
# I have attempted the following
# a dead end code that I cannot make work
# df = coincident[coincident['calendar_timestamp'].between(starting_point, ending_point)]
# print(df.head(n = 5))
# =============================================================================

# =============================================================================
# I have attempted the following but it will not work
# another dead end code
# for timestamp in coincident_events.calendar:
#     print(coincident_events.calendar.query('coincident_events.calendar >= emergency_events.starting_point and coincident_events.calendar <= emergency_events.ending_point'))
# =============================================================================

print(coincident.head(n = 20))

# =============================================================================
# Step 4: verify the "coincident" table is correct and then analyze the data
# Printing the "coincident" dataframe should look something like:
# =============================================================================
#     StartTime                       TrucksWorking    
# 0  2020-01-01 00:00:28              1
# 1  2020-01-01 00:01:28              1
# 2  2020-01-01 00:02:28              1
# 3  2020-01-01 00:03:28              1
# 4  2020-01-01 00:04:28              2
# 5  2020-01-01 00:05:28              2
# 6  2020-01-01 00:06:28              3
# 7  2020-01-01 00:07:28              3
# 8  2020-01-01 00:08:28              3
# 9  2020-01-01 00:09:28              3
# 10 2020-01-01 00:10:28              3
# etc for a full calendar year of ambulance responses

# =============================================================================
# Step 5: analyze the data looking for patterns of ambulance utilization. TBD
# =============================================================================

1 Ответ

0 голосов
/ 27 мая 2020

Используя ваши данные, я нашел следующее решение. Я использовал только первые 200 минут 2020 года , но вы можете легко изменить это, настроив periods=200 на количество минут в год.

Я использовал следующее variables: df соответствует вашему совпадающему кадру данных. Я сгенерировал его заранее для каждой минуты с 1 января 2020 года:

import pandas as pd
import datetime
df = pd.DataFrame()
df['time1'] = pd.date_range('2020-01-01 00:00:00', periods=200, freq='min')
df['trucks working'] = 0
print(df)

Это дает мне минуты года, когда все грузовики работают = 0 :

                  time1  trucks working
0   2020-01-01 00:00:00               0
1   2020-01-01 00:01:00               0
2   2020-01-01 00:02:00               0
3   2020-01-01 00:03:00               0
4   2020-01-01 00:04:00               0
..                  ...             ...
195 2020-01-01 03:15:00               0
196 2020-01-01 03:16:00               0
197 2020-01-01 03:17:00               0
198 2020-01-01 03:18:00               0
199 2020-01-01 03:19:00               0

Используя ваши экстренные вызовы как data

data = [['2020-01-01 00:00:28.000','2020-01-01 00:35:28.987']
    , ['2020-01-01 00:02:34.000','2020-01-01 01:05:13.540']
    , ['2020-01-01 00:03:57.000','2020-01-01 01:14:44.537']
    , ['2020-01-01 00:06:17.000','2020-01-01 01:26:52.087']
    , ['2020-01-01 00:13:20.000','2020-01-01 01:17:31.310']
    , ['2020-01-01 00:14:01.000','2020-01-01 01:57:28.343']
    , ['2020-01-01 00:16:11.000','2020-01-01 00:39:34.967']
    , ['2020-01-01 00:22:03.000','2020-01-01 01:46:40.037']
    , ['2020-01-01 00:23:07.000','2020-01-01 00:49:25.890']
    , ['2020-01-01 00:23:19.000','2020-01-01 01:26:39.920']
    , ['2020-01-01 00:30:17.000','2020-01-01 00:38:05.000']] 

Я добавляю имена столбцов и называю получившийся фрейм данных emergency_events:

 emergency_events = pd.DataFrame(data, columns = ['StartTime', 'EndTime'])

Теперь я могу перебирать фрейм данных emergency_events

и увеличиваем 'trucks working' для каждой минуты дня, которая находится между строкой 'StartTime' и 'EndTime'

for index2, row2 in df.iterrows():
for index, row in emergency_events.iterrows():
    if pd.to_datetime(row['StartTime']) <= pd.to_datetime(row2['time1']) <= pd.to_datetime(row['EndTime']):
        #print(row2['trucks working'])
        #print(row['StartTime'],row2['time1'],row['EndTime'])
        df.at[index2,'trucks working'] += 1

Это дает мне фрейм данных с номером грузовиков за каждую минуту в день.

time1  trucks working
0   2020-01-01 00:00:00               0
1   2020-01-01 00:01:00               1
2   2020-01-01 00:02:00               1
3   2020-01-01 00:03:00               2
4   2020-01-01 00:04:00               3
..                  ...             ...
195 2020-01-01 03:15:00               0
196 2020-01-01 03:16:00               0
197 2020-01-01 03:17:00               0
198 2020-01-01 03:18:00               0
199 2020-01-01 03:19:00               0
...