Лучшая структура данных для эффективного поиска по дате в R - PullRequest
0 голосов
/ 01 июля 2018

У меня есть фрейм данных, df, который содержит трафик через лондонские станции метро за каждый час в 2018 году:

        Year    Month Day  Hour    Station.ID    Traffic
1       2018    1     1    0       A             1000
2       2018    1     1    0       B             1300
3       2018    1     1    0       C             956
4       2018    1     1    0       D             721
...

Это более 7 000 000 строк. Я хотел бы получить эффективный способ поиска трафика в определенные даты и время. Например, если бы я хотел узнать трафик на станции «X» в 10:00 4/5/2018, я бы сейчас выполнил:

df[df$Year==2018 & df$Month==5 & df$Day==4 & df$Hour==10 & df$Station.ID=='X',]$Traffic

Но этот метод без необходимости просматривает весь фрейм данных. Моя идея состоит в том, чтобы организовать данные в иерархическую структуру следующим образом:

library(data.tree)
df$pathString <- paste("MyTree", 
                        df$Year, 
                        df$Month,
                        df$Day,
                        df$Hour,
                        df$Station.ID,
                        sep = "/")
dftree <- as.Node(df)

Мой предыдущий запрос теперь будет выглядеть так:

dftree$'2018'$'5'$'4'$'10'$X$Traffic

и это будет на порядки быстрее. Моя проблема в том, что на самом деле требуется слишком много времени, чтобы фактически организовать df в дерево! Если я возьму подмножество из 1000 строк, то это займет пару минут. Со всеми 7 000 000 рядов он сгорает без конца.

Мои вопросы:

1) Какая структура данных наиболее подходит для быстрого поиска, когда данные упорядочены по дате?

2) Является ли df слишком большим, чтобы эта структура подходила?

1 Ответ

0 голосов
/ 01 июля 2018

A data.table.

Используя набор данных flights, такой запрос, как ваш, занимает около полсекунды:

library(data.table)
library(nycflights13)
flights <- as.data.table(flights)
flights7M <- rbindlist(lapply(1:22, function(x) flights))

nrow(flights7M) / 7e6  # close enough
#> [1] 1.058439

bench::system_time({
  setkey(flights7M, year, month, day, hour, origin)
  flights7M[.(2013L, 5L, 4L, 10L, "JFK")]
})
#> process    real 
#>    1.8s 587.4ms

Создано в 2018-07-02 пакетом Представление (v0.2.0).

...