Поиск…


Вступление

Ключ и индексы таблицы данных позволяют некоторым вычислениям работать быстрее, в основном связанные с объединениями и подмножеством. Ключ описывает текущий порядок сортировки таблицы; в то время как каждый индекс хранит информацию о порядке таблицы с учетом последовательности столбцов. См. Раздел «Примечания» ниже для ссылок на официальные виньетки на эту тему.

замечания

Официальные виньетки - лучшее введение в эту тему:

Ключи против индексов

Таблицу данных можно «закрепить» по последовательности столбцов, сообщая заинтересованным функциям, что данные сортируются по этим столбцам. Чтобы получить или установить ключ, используйте функции, задокументированные ?key .

Точно так же функции могут использовать «индексы» data.table. Каждый индекс - и таблица может иметь более одного - хранит информацию о порядке данных с учетом последовательности столбцов. Как ключ, индекс может ускорить выполнение определенных задач. Чтобы получить или установить индексы, используйте функции, задокументированные по ?indices .

Индексы также могут быть установлены автоматически (в настоящее время только для одного столбца за раз). См. ?datatable.optimize для получения подробной информации о том, как это работает и как отключить его, если необходимо.

Проверка и обновление

Недопустимые значения разрешены в ключевом столбце.

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

Ключи и индексы удаляются после обновлений, где не очевидно, что порядок сортировки сохраняется. Например, начиная с DT = data.table(a=c(1,2,4), key="a") , если мы обновляем как DT[2, a := 3] , ключ сломан.

Улучшение производительности для выбора подмножеств

# example data
set.seed(1)
n  = 1e7
ng = 1e4
DT = data.table(
    g1  = sample(ng, n, replace=TRUE),
    g2  = sample(ng, n, replace=TRUE),
    v  = rnorm(n)
)

Соответствие по одному столбцу

После первого запуска операции подмножества с == или %in% ...

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#    0.12    0.03    0.16 

Индекс был создан автоматически для g1 . Последующие операции подмножества выполняются почти мгновенно:

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#       0       0       0

Чтобы отслеживать, когда индекс создан или используется, добавьте параметр verbose=TRUE или измените параметры глобальной настройки options(datatable.verbose=TRUE) .

Согласование по нескольким столбцам

В настоящее время сопоставление по двум столбцам не создает автоматически индекс:

system.time(
    DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
#    user  system elapsed 
#    0.57    0.00    0.57

Повторно запустите это, и он будет оставаться медленным. Даже если мы вручную добавим индекс с помощью setindex(DT, g1, g2) , он будет оставаться медленным, потому что этот запрос еще не оптимизирован пакетом.

К счастью, если мы можем перечислить комбинации значений, которые мы хотим найти, и индекс доступен, мы можем быстро equi-join:

system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#    0.53    0.00    0.54 
setindex(DT, g1, g2)
system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#       0       0       0

С CJ важно следить за тем, чтобы количество комбинаций становилось слишком большим.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow