๋๋ ์ด data.table ํญ๋ชฉ์ ์ข์ํฉ๋๋ค. ์คํ ์๋์ ์คํฌ๋ฆฝํ
์ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ๊ณ ๋ฅด๊ฒ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
์์ ํ
์ด๋ธ์๋ ์ ์ฌ์ฉํ๊ณ ์์ด์.
๋๋ ์ ๊ธฐ์ ์ผ๋ก DT[, .(id1, id5)]์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ํ
์ด๋ธ์ ํ์ ์งํฉ์ ๋ง๋ญ๋๋ค.
์ด ๋ฐฉ๋ฒ์ด ์๋๋๋ค: DT[, c("id1", "id5")]
์ค๋ ๋๋ ๋ ์ฌ๋์ ์๋๋ฅผ ์ธก์ ํ๊ณ ๋๋ ์์ ํ ์ด๋ธ์ ์๋ ์ฐจ์ด์ ๋๋์ต๋๋ค. ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ํจ์ฌ ๋๋ฆฝ๋๋ค.
์ด ์ฐจ์ด๊ฐ ์๋๋ ๊ฒ์ ๋๊น?
์คํ ์๋ ์ธก๋ฉด์์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์๋ ดํ๋ ๊ฐ๊ฒฐํ ๋ฐฉ๋ฒ์ ๋ง๋ค๊ณ ์ ํ๋ ์ด๋ง์ด ์์ต๋๊น?
(๋ฐ๋ณต์ ์ธ ๋ฐฉ์์ผ๋ก ์ฌ๋ฌ ๊ฐ์ ์์ ํ
์ด๋ธ์ ํ์ ์งํฉ์ผ๋ก ๋ง๋ค์ด์ผ ํ ๋ ๊ณ์ฐ๋ฉ๋๋ค.)
์ฐ๋ถํฌ 18.04
R ๋ฒ์ 3.5.3(2019-03-11)
data.table 1.12.0
๋จ 32GB
Intelยฎ Coreโข i7-8565U CPU @ 1.80GHz ร 8
library(data.table)
library(microbenchmark)
N <- 2e8
K <- 100
set.seed(1)
DT <- data.table(
id1 = sample(sprintf("id%03d", 1:K), N, TRUE), # large groups (char)
id2 = sample(sprintf("id%03d", 1:K), N, TRUE), # large groups (char)
id3 = sample(sprintf("id%010d", 1:(N/K)), N, TRUE), # small groups (char)
id4 = sample(K, N, TRUE), # large groups (int)
id5 = sample(K, N, TRUE), # large groups (int)
id6 = sample(N/K, N, TRUE), # small groups (int)
v1 = sample(5, N, TRUE), # int in range [1,5]
v2 = sample(5, N, TRUE), # int in range [1,5]
v3 = sample(round(runif(100, max = 100), 4), N, TRUE) # numeric e.g. 23.5749
)
microbenchmark(
DT[, .(id1, id5)],
DT[, c("id1", "id5")]
)
Unit: seconds
expr min lq mean median uq max neval
DT[, .(id1, id5)] 1.588367 1.614645 1.929348 1.626847 1.659698 12.33872 100
DT[, c("id1", "id5")] 1.592154 1.613800 1.937548 1.628082 2.184456 11.74581 100
N <- 2e5
DT2 <- data.table(
id1 = sample(sprintf("id%03d", 1:K), N, TRUE), # large groups (char)
id2 = sample(sprintf("id%03d", 1:K), N, TRUE), # large groups (char)
id3 = sample(sprintf("id%010d", 1:(N/K)), N, TRUE), # small groups (char)
id4 = sample(K, N, TRUE), # large groups (int)
id5 = sample(K, N, TRUE), # large groups (int)
id6 = sample(N/K, N, TRUE), # small groups (int)
v1 = sample(5, N, TRUE), # int in range [1,5]
v2 = sample(5, N, TRUE), # int in range [1,5]
v3 = sample(round(runif(100, max = 100), 4), N, TRUE) # numeric e.g. 23.5749
)
microbenchmark(
DT2[, .(id1, id5)],
DT2[, c("id1", "id5")]
)
Unit: microseconds
expr min lq mean median uq max neval
DT2[, .(id1, id5)] 1405.042 1461.561 1525.5314 1491.7885 1527.8955 2220.860 100
DT2[, c("id1", "id5")] 614.624 640.617 666.2426 659.0175 676.9355 906.966 100
์ฝ๋ ์ฒญํฌ ์๋ค์ ๋ฐฑํฑ ์ธ ์ค์ ์ฌ์ฉํ์ฌ ๊ฒ์๋ฌผ ํ์์ ์์ ํ ์ ์์ต๋๋ค.
```
code
```
์ฌ๋ฌ ๊ฐ์ ์์ ํ ์ด๋ธ์ ๋ฐ๋ณต์ ์ธ ๋ฐฉ์์ผ๋ก ๋ถ๋ถ์งํฉํด์ผ ํ ๋ ๊ณ์ฐ๋ฉ๋๋ค.
์์ ํ
์ด๋ธ์์ ๋ฐ๋ณต์ ์ผ๋ก ์ด์ ์ ํํ๋ ๊ฒ์ ํผํด์ผ ํ๊ณ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ํผํ ์ ์๋ ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค...? j
in DT[i, j, by]
๋ ์ด์ฒ๋ผ ๋ค์ํ ์
๋ ฅ์ ์ง์ํ๊ณ ์ต์ ํํ๊ธฐ ๋๋ฌธ์ ํ์ฑ์ ์ฝ๊ฐ์ ์ค๋ฒํค๋๊ฐ ์๋ ๊ฒ์ ๋น์ฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฌธ์ ์ ์ ๊ทผํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จํ์ฌ(๊ทธ๋ฆฌ๊ณ ๋ ์์ธํ ์ด์ผ๊ธฐํ๊ณ ์ถ๋ค๋ฉด ์ด๊ฒ์ด ์คํ ์ค๋ฒํ๋ก์ ๋ ์ ํฉํ ๊ฒ์
๋๋ค) ... ํ
์ด๋ธ์์ ์ํํ๋ ค๋ ๋ค๋ฅธ ์์
์ ๋ฐ๋ผ ๋ค๋ฅธ ์ด์ ์ญ์ ํ ์ ์์ต๋๋ค. , DT[, setdiff(names(DT), cols) := NULL]
๋ฐ DT๋ฅผ ์ง์ ๊ณ์ ์ฌ์ฉํฉ๋๋ค.
์ฌ์ ํ ํ์ ์งํฉ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํ๋ ๊ฒฝ์ฐ ์ด ํฌ์ธํฐ๋ฅผ ์ก๋ ๊ฒ์ด ์ฌ๊ธฐ์์ ๊ณ ๋ คํ ๋ ์ต์ ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด์ง๋ง ์ด ๋ฐฉ๋ฒ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ํธ์งํ๋ฉด ์๋ณธ ํ ์ด๋ธ์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
library(data.table)
library(microbenchmark)
N <- 2e8
K <- 100
set.seed(1)
DT <- data.table(
id1 = sprintf("id%03d", 1:K), # large groups (char)
id2 = sprintf("id%03d", 1:K), # large groups (char)
id3 = sprintf("id%010d", 1:(N/K)), # small groups (char)
id4 = sample(K), # large groups (int)
id5 = sample(K), # large groups (int)
id6 = sample(N/K), # small groups (int)
v1 = sample(5), # int in range [1,5]
v2 = sample(5), # int in range [1,5]
v3 = round(runif(100, max = 100), 4), # numeric e.g. 23.5749
row = seq_len(N)
)
cols = c("id1", "id5")
microbenchmark(times = 3,
expression = DT[, .(id1, id5)],
index = DT[, c("id1", "id5")],
dotdot = DT[, ..cols],
oddball = setDT(lapply(setNames(cols, cols), function(x) DT[[x]]))[],
oddball2 = setDT(unclass(DT)[cols])[]
)
Unit: microseconds
expr min lq mean median uq max neval
expression 1249753.580 1304355.3415 1417166.9297 1358957.103 1500873.6045 1642790.106 3
index 1184056.302 1191334.4835 1396372.3483 1198612.665 1502530.3715 1806448.078 3
dotdot 1084521.234 1240062.2370 1439680.6980 1395603.240 1617260.4300 1838917.620 3
oddball 92.659 171.8635 568.5317 251.068 806.4680 1361.868 3
oddball2 66.582 125.9505 150.7337 185.319 192.8095 200.300 3
(๋๋ ์ฐธ์์ฑ์ด ์์๊ธฐ ๋๋ฌธ์ ๊ทํ์ ์์์์ ๋ฌด์์ ์ถ์ถ์ ์ ํํ๊ณ ๋ฒค์น๋งํฌ์์ #๋ฐฐ๋ฅผ ์ค์์ต๋๋ค.)
R์ ๋ชฉ๋ก ํ์ ์งํฉ(์์ unclass
๋ค์์ ์ฌ์ฉ๋จ)์ ์ง์ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
"๊ฒฐ๊ณผ๋ฅผ ํธ์งํ๋ฉด ์๋ ํ ์ด๋ธ์ด ์์ ๋ฉ๋๋ค"์ ๊ด๋ จํ์ฌ ๋ค์์ ์๋ฏธํฉ๋๋ค.
myDT = data.table(a = 1:2, b = 3:4)
# standard way
res <- myDT[, "a"]
res[, a := 0]
myDT
# a b
# 1: 1 3
# 2: 2 4
# oddball, grabbing pointers
res2 <- setDT(unclass(myDT)["a"])
res2[, a := 0]
myDT
# a b
# 1: 0 3
# 2: 0 4
์ข์, ๋๋ ์ค๋ ์๋กญ๊ณ ๋น ๋ฅธ(์ด์ํ) ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐฐ์ ๊ณ ์๋์ ๊ฐ๊ฒฐํ ์ฝ๋ฉ ์ฌ์ด์ ๊ท ํ์ด ์๋ค๋ ์ ์ ์ฃผ๋ชฉํ๊ณ ์์ต๋๋ค. ๊ทธ๋์ ์์ด ๋ฐ์ฏค ์ฐจ ์์ต๋๋ค! ๊ฐ์ฌ ํด์!
#852 ๊ด๋ จ์ด ์๋ ๊ฒ ๊ฐ์์
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฝ๋ ์ฒญํฌ ์๋ค์ ๋ฐฑํฑ ์ธ ์ค์ ์ฌ์ฉํ์ฌ ๊ฒ์๋ฌผ ํ์์ ์์ ํ ์ ์์ต๋๋ค.
์์ ํ ์ด๋ธ์์ ๋ฐ๋ณต์ ์ผ๋ก ์ด์ ์ ํํ๋ ๊ฒ์ ํผํด์ผ ํ๊ณ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ํผํ ์ ์๋ ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค...?
j
inDT[i, j, by]
๋ ์ด์ฒ๋ผ ๋ค์ํ ์ ๋ ฅ์ ์ง์ํ๊ณ ์ต์ ํํ๊ธฐ ๋๋ฌธ์ ํ์ฑ์ ์ฝ๊ฐ์ ์ค๋ฒํค๋๊ฐ ์๋ ๊ฒ์ ๋น์ฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค.๋ฌธ์ ์ ์ ๊ทผํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จํ์ฌ(๊ทธ๋ฆฌ๊ณ ๋ ์์ธํ ์ด์ผ๊ธฐํ๊ณ ์ถ๋ค๋ฉด ์ด๊ฒ์ด ์คํ ์ค๋ฒํ๋ก์ ๋ ์ ํฉํ ๊ฒ์ ๋๋ค) ... ํ ์ด๋ธ์์ ์ํํ๋ ค๋ ๋ค๋ฅธ ์์ ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ด์ ์ญ์ ํ ์ ์์ต๋๋ค. ,
DT[, setdiff(names(DT), cols) := NULL]
๋ฐ DT๋ฅผ ์ง์ ๊ณ์ ์ฌ์ฉํฉ๋๋ค.์ฌ์ ํ ํ์ ์งํฉ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํ๋ ๊ฒฝ์ฐ ์ด ํฌ์ธํฐ๋ฅผ ์ก๋ ๊ฒ์ด ์ฌ๊ธฐ์์ ๊ณ ๋ คํ ๋ ์ต์ ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด์ง๋ง ์ด ๋ฐฉ๋ฒ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ํธ์งํ๋ฉด ์๋ณธ ํ ์ด๋ธ์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
(๋๋ ์ฐธ์์ฑ์ด ์์๊ธฐ ๋๋ฌธ์ ๊ทํ์ ์์์์ ๋ฌด์์ ์ถ์ถ์ ์ ํํ๊ณ ๋ฒค์น๋งํฌ์์ #๋ฐฐ๋ฅผ ์ค์์ต๋๋ค.)
R์ ๋ชฉ๋ก ํ์ ์งํฉ(์์
unclass
๋ค์์ ์ฌ์ฉ๋จ)์ ์ง์ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค."๊ฒฐ๊ณผ๋ฅผ ํธ์งํ๋ฉด ์๋ ํ ์ด๋ธ์ด ์์ ๋ฉ๋๋ค"์ ๊ด๋ จํ์ฌ ๋ค์์ ์๋ฏธํฉ๋๋ค.