data.table에서 키를 설정하는 목적은 무엇입니까?
는 사용중을 하고 있습니다.data.table
키설해야하예많기있습다니이능은는정를예▁which(:▁(다있▁and)이 많습니다.X[Y]
가 어떤 역할을 따라서 데이터 테이블에서 키를 올바르게 설정하기 위해 키가 어떤 역할을 하는지 알고 싶습니다.
내가 읽은 한 출처는?setkey
.
setkey()
.data.table
정렬된 것으로 표시합니다.정렬된 열이 키입니다.키는 임의의 순서의 열이 될 수 있습니다.열은 항상 오름차순으로 정렬됩니다.테이블이 참조로 변경됩니다.하나의 열만큼 큰 임시 작업 메모리를 제외하고는 복사본이 전혀 생성되지 않습니다.
을 " "데이터".table과 입니다.order()
하지만, 그것은 열쇠를 갖는 목적을 설명하지 않습니다.
data.table FAQ 3.2 및 3.3은 다음을 설명합니다.
3.2 큰 테이블에 키가 없지만 그룹화는 매우 빠릅니다.왜 그런 것일까요?
sorting.data.table을 사용합니다.이것은 다른 정렬 알고리즘보다 훨씬 빠릅니다.됩니다. 를 참조하십시오. 참조
?base::sort.list(x,method="radix")
이것은 또한 이유중 하나입니다.setkey()
되어 있지 바이라고 .키가 설정되어 있지 않거나 키의 순서와 다른 순서로 그룹화할 경우 이를 애드혹이라고 합니다.3.3 키의 열을 기준으로 그룹화하는 것이 애드혹보다 빠른 이유는 무엇입니까?
에 페이지으로 복사할 수 .
memcpy
C에서 루프하는 것보다 C에서).
여기서, 키를 설정하면 어떻게든 R이 다른 알고리즘보다 "기수 정렬"을 사용할 수 있고, 그래서 더 빠르다고 생각합니다.
10분짜리 퀵 스타트 가이드에는 키에 대한 가이드도 나와 있습니다.
- 열쇠들.
먼저 data.frame, 특히 행 이름(또는 영어로 행 이름)을 고려해 보겠습니다.즉, 단일 행에 속하는 여러 이름입니다.단일 행에 속하는 여러 이름?그것은 우리가 data.frame에서 익숙한 것이 아닙니다.각 행에는 최대 하나의 이름이 있습니다.사용자는 최소 두 개의 이름, 즉 예술 이름과 두 번째 이름을 가지고 있습니다.이는 예를 들어 성, rst 이름 순으로 정렬된 전화 디렉토리를 구성하는 데 유용합니다.그러나 data.frame의 각 행은 이름을 하나만 가질 수 있습니다.
키는 단순히 문자가 아닌 정수, 요인, 문자 또는 일부 다른 클래스일 수 있는 하나 이상의 행 이름 열로 구성됩니다.또한 행은 키별로 정렬됩니다.따라서 data.table은 둘 이상의 방법으로 정렬할 수 없기 때문에 최대 하나의 키를 가질 수 있습니다.
고유성이 적용되지 않습니다. 즉, 중복 키 값이 허용됩니다.행이 키별로 정렬되므로 키의 중복 항목이 연속적으로 나타납니다.
전화번호부는 키가 무엇인지 이해하는 데 도움이 되었지만, 요인 열이 있는 것과 비교했을 때 키는 다르지 않은 것 같습니다.또한 키가 필요한 이유(특히 특정 기능을 사용하는 경우)와 키로 설정할 열을 선택하는 방법에 대해서는 설명하지 않습니다.또한 시간을 열로 하는 data.table에서 다른 열을 키로 설정하면 시간 열도 엉망이 될 수 있으므로 다른 열을 키로 설정할 수 있는지 여부를 알 수 없어 더욱 혼란스럽습니다.누가 좀 가르쳐 주시겠어요?
이 답변 외에도 2차 인덱스 및 자동 인덱싱 및 키와 빠른 이진 검색 기반 하위 집합을 참조하십시오.
이 문제는 우리가 계획하고 있는 다른 vignett을 강조합니다.
이 월새로것비에추년어운저다는다니 (2016년에 업데이트했습니다.on=
애드혹 조인도 허용하는 기능입니다.이전(오래된) 답변은 내역을 참조하십시오.
정확히 무엇을 합니까?setkey(DT, a, b)
하십니까?
두 가지 작업을 수행합니다.
- data.table의 행 순서를 변경합니다.
DT
(a, b) 참조에 의해 제공된 열에 의해, 항상 증가하는 순서로. - 다음과 같은 속성을 설정하여 해당 열을 키 열로 표시합니다.
sorted
DT
.
재주문은 (data.table의 내부 기수 정렬로 인해) 빠르고 메모리 효율적입니다(두 배 유형의 추가 열 하나만 할당됨).
는 언제입니까?setkey()
필요합니까?
작업의 에는 "그룹화"를 사용합니다.setkey()
절대적인 요구사항은 아니었습니다.즉, 콜드 바이 또는 애드 바이를 수행할 수 있습니다.
## "cold" by
require(data.table)
DT <- data.table(x=rep(1:5, each=2), y=1:10)
DT[, mean(y), by=x] # no key is set, order of groups preserved in result
그나이는에전 v1.9.6
x[i]
수의key
를 x
v1.9.6+의 새로운 인수를 사용하면 더 이상 사실이 아니며, 따라서 키를 설정하는 것이 여기서도 절대적인 요구 사항은 아닙니다.
## joins using < v1.9.6
setkey(X, a) # absolutely required
setkey(Y, a) # not absolutely required as long as 'a' is the first column
X[Y]
## joins using v1.9.6+
X[Y, on="a"]
# or if the column names are x_a and y_a respectively
X[Y, on=c("x_a" = "y_a")]
:on=
인수는다음대에명지수있정다습니할로시으적도해서▁▁for에 대해서도 인수를 명시적으로 할 수 .keyed
조인도 합니다.
입니다.
key
절대적으로 설정되는 것은 포버랩스(foverlaps) 함수입니다.그러나 우리는 이 요구 사항을 제거할 수 있는 몇 가지 기능을 더 연구하고 있습니다.
그래서 구현해야 하는 이유는 무엇입니까?
on=
논쟁?여러 가지 이유가 있습니다.
두 개의 data.tables가 포함된 작업으로 작업을 명확하게 구분할 수 있습니다.그냥 하는 중
X[Y]
변수의 이름을 적절하게 지정하면 명확해질 수 있지만 에서는 이도 구분하지 않습니다.또한 코드 라인을 보고 즉시 조인/부분 집합이 수행되는 열을 이해할 수 있습니다(해당하는 열로 다시 추적할 필요가 없음).
setkey()
선)을 선택합니다.기준으로 열을 추가하거나 업데이트하는 작업에서는
on=
열을 추가/업데이트하기 위해 전체 data.table을 다시 정렬할 필요가 없기 때문에 작업 성능이 훨씬 더 우수합니다.를 들면 를들면예,## compare setkey(X, a, b) # why physically reorder X to just add/update a column? X[Y, col := i.val] ## to X[Y, col := i.val, on=c("a", "b")]
두 번째 경우, 우리는 재주문할 필요가 없었습니다.시간이 많이 걸리는 주문을 계산하는 것이 아니라 RAM에서 data.table을 물리적으로 다시 정렬하고 이를 피함으로써 원래 주문을 유지하고 성능도 향상됩니다.
그렇지 않은 경우에도 조인을 반복적으로 수행하지 않는 한 키가 있는 조인과 임시 조인 사이에 성능 차이가 발생하지 않아야 합니다.
따라서 data.table 키를 사용하는 것이 더 이상 어떤 이점이 있습니까?라는 질문이 나옵니다.
data.table을 유지하면 이점이 있습니까?
data.table을 키로 지정하면 RAM의 해당 열을 기준으로 물리적으로 정렬됩니다.주문을 계산하는 것은 일반적으로 시간이 많이 걸리는 부분이 아니라 재주문 자체입니다.그러나 데이터를 RAM으로 정렬하면 동일한 그룹에 속한 행이 모두 RAM으로 연속되므로 캐시 효율성이 매우 높습니다.정렬을 통해 키가 지정된 data.tables에 대한 작업 속도를 높일 수 있습니다.
따라서 전체 data.table을 다시 정렬하는 데 소요되는 시간이 캐시 효율적인 조인/집약을 수행하는 데 필요한 시간인지 여부를 파악하는 것이 중요합니다.일반적으로 동일한 keyed data.table에서 반복적인 그룹화/조인 작업이 수행되지 않는 한, 눈에 띄는 차이가 없어야 합니다.
따라서 대부분의 경우 더 이상 키를 설정할 필요가 없습니다.을 사용하는 것이 좋습니다.
on=
가능한 한 키를 설정하는 것이 성능을 크게 향상시키지 않는 한 활용할 수 있습니다.
질문:만약 당신이 사용한다면, 당신은 키가 있는 조인과 비교했을 때 성능이 어떨 것이라고 생각합니까?setorder()
데이터를 다시 정렬하고 사용합니다.on=
지금까지 따라왔으면 알 수 있을 거예요 :-).
키는 기본적으로 데이터셋의 인덱스로, 매우 빠르고 효율적으로 정렬, 필터링 및 조인 작업을 수행할 수 있습니다.이러한 이유로 데이터 프레임 대신 데이터 테이블을 사용하는 것이 가장 좋습니다(데이터 테이블을 사용하는 구문도 훨씬 사용자 친화적이지만 키와는 관련이 없습니다).
색인을 이해할 수 없는 경우, 전화번호부는 이름별로 "색인"됩니다.그래서 만약 제가 누군가의 전화번호를 찾고 싶다면, 그것은 꽤 간단합니다.그러나 전화 번호(예: 특정 전화 번호를 가진 사람을 검색)로 검색한다고 가정해 보겠습니다.전화 번호로 전화번호부를 "재색인"할 수 없는 한, 매우 오랜 시간이 걸릴 것입니다.
다음 예를 생각해 보십시오. 관련 정보(도시, 주, 인구, 중위 소득 등)와 함께 미국의 모든 우편 번호(33,000명 이상)에 대한 표 ZIP가 있다고 가정합니다.특정 우편 번호에 대한 정보를 조회하려면 검색(필터)이 1000배 더 빠릅니다.setkey(ZIP, zipcode)
또 다른 이점은 조인과 관련이 있습니다.데이터 테이블에 사용자 및 해당 우편 번호 목록("PPL"이라고 함)이 있고 ZIP 테이블의 정보(예: 시, 시 등)를 추가하려고 합니다.다음 코드가 이를 수행합니다.
setkey(ZIP, zipcode)
setkey(PPL, zipcode)
full.info <- PPL[ZIP, nomatch = FALSE]
이것은 공통 필드(zipcode)에 기반한 두 테이블의 정보를 결합한다는 의미에서 "결합"입니다.매우 큰 테이블에서 이와 같은 조인은 데이터 프레임에서는 매우 느리고 데이터 테이블에서는 매우 빠릅니다.실제 사례에서 저는 우편번호의 전체 테이블에서 20,000개 이상의 조인을 해야 했습니다.데이터 테이블의 경우 스크립트를 실행하는 데 약 20분이 걸렸습니다.2주 이상 걸릴 것 같아서 데이터 프레임으로도 시도하지 않았습니다.
IMHO 당신은 단지 FAQ와 소개 자료를 읽는 것이 아니라 공부해야 합니다.이것을 적용할 실제 문제가 있는 경우 파악하기가 더 쉽습니다.
[@Frank의 논평에 대한 반응]
참조: 정렬 대 인덱싱 - 이 질문에 대한 대답을 기준으로 다음과 같이 표시됩니다.setkey(...)
테이블의 열을 실제로 재정렬하고(예: 실제 정렬) 데이터베이스 의미의 인덱스를 만들지 않습니다.이것은 몇 가지 실질적인 의미를 가지고 있습니다: 한 가지 예로, 만약 당신이 다음과 같은 표에서 키를 설정한다면.setkey(...)
키더 정렬되지 입니다(" " " " " " data.table"을 하면 됩니다).sorted
데이터베이스에서 발생하는 것처럼 적절한 정렬 순서를 유지하기 위해 동적으로 다시 인덱싱하지 않습니다.또한 다음을 사용하여 "키 제거"setkey(DT, NULL)
테이블을 정렬되지 않은 원래 순서로 복원하지 않습니다.
Re: 필터 대 조인 - 필터링은 단일 데이터 세트에서 부분 집합을 추출하는 반면 조인은 공통 필드를 기반으로 두 데이터 세트의 데이터를 결합한다는 것이 실질적인 차이점입니다.다양한 종류의 조인(내부, 외부, 왼쪽)이 있습니다.위의 예는 내부 조인(두 테이블에 공통 키가 있는 레코드만 반환됨)이며 필터링과 유사한 점이 많습니다.
언급URL : https://stackoverflow.com/questions/20039335/what-is-the-purpose-of-setting-a-key-in-data-table
'programing' 카테고리의 다른 글
문자열 변수에서 모듈 가져오기 (0) | 2023.06.10 |
---|---|
JPA 수준에서 잠긴 업데이트 건너뛰기에 대한 선택 (0) | 2023.06.10 |
다른 모든 요청에 대한 Kubernetes Traefik 내부 서버 오류 (0) | 2023.06.10 |
ggplot은 for 루프 내부에 있으면 작동하지 않지만 외부에서 작동합니다. (0) | 2023.06.10 |
setsid() 앞에 포크()가 있는 이유 (0) | 2023.06.10 |