2015-10-12 2 views
0

Это та же проблема, что и в 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; то при необходимости обновляет начало и конец первых/последних интервалов (если начало и конец запроса находится в пределах первого и последнего интервала) и суммирует разницу во времени в пределах интервалов.

Будет оценено любое умное ускорение.

+1

Спасибо, изменилось. –

+1

Взгляните на '? Foverlaps' –

ответ

0

Непроверено

library(dplyr) 
calc_sw_intervals <- function(df, start, end){ 
    df %>% 
    filter(start < configEndDate, configStartDate < end) %>% 
    mutate(
     delta = pmin(configEndDate, end) - pmax(configStartDate, start) 
    ) %>% 
    summarise(Total = sum(delta)) 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^