Это та же проблема, что и в this question, но теперь я заинтересован в ускорении моей функции. Я скопирую-вставьте описание проблемы и мой R-код, который работает около 36 мс на строку, что слишком длится для количества строк, которые у меня есть.Ускорение линейного интервала обновления/добавления в data.table
Проблема:
У меня есть несколько наборов данных, каждый из которых имеет промежутки времени следующим образом:
configStartDate configEndDate
2012-06-07 10:38:01.000 2012-06-11 13:35:25.000
2012-07-12 20:00:55.000 2012-07-17 10:17:53.000
2012-07-18 12:44:15.000 2012-07-20 02:15:47.000
2012-07-20 02:15:47.000 2012-10-05 10:35:19.000
2012-10-05 10:35:19.000 2012-11-13 10:44:24.000
Мне нужно написать функцию запроса (в R, но я просто выяснить логику прямо сейчас, прототипирование в Python), который будет принимать две пользовательские даты начала и окончания и суммировать промежутки между ними.
Проблема в том, что даты запроса могут начинаться посередине или за пределами временных блоков. Так, например, в приведенном выше примере мой запрос может быть для временного интервала 2012-06-09 и 2012-11-11, и в этом случае мне придется изменить даты начала и окончания первого и последнего фрагментов. Но, первый интервал может также начаться в середине второго куска, и т.д., и т.д.
R Код:
# calculating time differences row-by-row:
soft_days <- soft_days[,
.(soft_days = calc_sw_intervals(soft_dt = soft_install_model,
start_query = start_q,
end_query = end_q,
assetID = assetId,
soft_mm = soft_major_minor),
by = c('assetId', 'soft_major_minor')
]
# code to sum up (custom) time intervals:
calc_sw_intervals <- function(soft_dt, start_query, end_query, assetID, soft_mm, dType = 1){
start_query <- ymd(start_query)
end_query <- ymd(end_query)
soft_dt <- soft_dt[assetId == assetID & soft_major_minor %in% soft_mm
& configEndDate > start_query
& configStartDate < end_query
& deviceType == dType
,list(configStartDate, configEndDate)
]
if(dim(soft_dt)[1] == 0)
return(NaN)
soft_dt[1, configStartDate := max(start_query, configStartDate)]
soft_dt[.N, configEndDate := min(end_query, configEndDate)]
total_days <- soft_dt[, sum(as.numeric(difftime(configEndDate, configStartDate, units = 'days')))]
return(total_days)
}
Что делает код, это найти все временные интервалы, когда конец интервала is>start_query
, начало интервала < end_query
; то при необходимости обновляет начало и конец первых/последних интервалов (если начало и конец запроса находится в пределах первого и последнего интервала) и суммирует разницу во времени в пределах интервалов.
Будет оценено любое умное ускорение.
Спасибо, изменилось. –
Взгляните на '? Foverlaps' –