减小 ID 字段大小的技巧
Tips for reducing the size of an ID field
我有一个包含 3000 万行的数据集。一些列包括非常大的整数的 ID 字段。例如
library(data.table)
dt <- data.table(SomeID = c(8762438732197823423,
1236487432893428732,
290234987238237842))
我怀疑减小这些 ID 的大小会加快对我的数据的连接和其他处理。这样做的好方法是什么?例如,我可以将唯一 ID 映射到 {1、2、3...} 或 {A、B、C、...}。也不确定哪种数据类型(整数或字符?)最适合存储这些 ID 字段。
R 中整数的最大大小为 2^31 - 1
,即 2147483647。大于该整数的整数可以存储在双精度数中,但正如@Roland 上面指出的那样,有效数的精度有限制53位,所以能准确存储的最大整数是2^53
。尝试 2^53 - (2^53 - 1)
,你会得到 1。尝试 (2^53 + 1) - 2^53
,你会得到 0。
对于您最初的问题,如果您谈论的是使用 data.table 联接,则内容不多:
library("data.table")
library("microbenchmark")
f <- d <- a <- data.table(x = runif(100, 0, 2^53 - 1), y = rnorm(100))
g <- e <- b <- data.table(x = sample(a$x, 40), z = rnorm(40))
d$x <- sample(1:100)
e$x <- d$x[match(b$x, a$x)]
f$x <- as.character(f$x)
g$x <- as.character(g$x)
setkey(a, x)
setkey(b, x)
setkey(d, x)
setkey(e, x)
setkey(f, x)
setkey(g, x)
microbenchmark(a[b], d[e], f[g], times = 1000L)
##Unit: microseconds
## expr min lq mean median uq max neval
## a[b] 569.079 623.0495 696.8870 649.4150 699.8465 4160.852 1000
## d[e] 570.141 621.2795 719.7463 647.6455 708.5170 5305.024 1000
## f[g] 549.968 598.4520 665.4203 622.8720 674.1880 3667.156 1000
如果你想这样做,你可以创建一个新的 data.frame 或 data.table,其中包含新旧 ID 的列,然后使用 match
函数,如上面的代码改变了 ids。
我有一个包含 3000 万行的数据集。一些列包括非常大的整数的 ID 字段。例如
library(data.table)
dt <- data.table(SomeID = c(8762438732197823423,
1236487432893428732,
290234987238237842))
我怀疑减小这些 ID 的大小会加快对我的数据的连接和其他处理。这样做的好方法是什么?例如,我可以将唯一 ID 映射到 {1、2、3...} 或 {A、B、C、...}。也不确定哪种数据类型(整数或字符?)最适合存储这些 ID 字段。
R 中整数的最大大小为 2^31 - 1
,即 2147483647。大于该整数的整数可以存储在双精度数中,但正如@Roland 上面指出的那样,有效数的精度有限制53位,所以能准确存储的最大整数是2^53
。尝试 2^53 - (2^53 - 1)
,你会得到 1。尝试 (2^53 + 1) - 2^53
,你会得到 0。
对于您最初的问题,如果您谈论的是使用 data.table 联接,则内容不多:
library("data.table")
library("microbenchmark")
f <- d <- a <- data.table(x = runif(100, 0, 2^53 - 1), y = rnorm(100))
g <- e <- b <- data.table(x = sample(a$x, 40), z = rnorm(40))
d$x <- sample(1:100)
e$x <- d$x[match(b$x, a$x)]
f$x <- as.character(f$x)
g$x <- as.character(g$x)
setkey(a, x)
setkey(b, x)
setkey(d, x)
setkey(e, x)
setkey(f, x)
setkey(g, x)
microbenchmark(a[b], d[e], f[g], times = 1000L)
##Unit: microseconds
## expr min lq mean median uq max neval
## a[b] 569.079 623.0495 696.8870 649.4150 699.8465 4160.852 1000
## d[e] 570.141 621.2795 719.7463 647.6455 708.5170 5305.024 1000
## f[g] 549.968 598.4520 665.4203 622.8720 674.1880 3667.156 1000
如果你想这样做,你可以创建一个新的 data.frame 或 data.table,其中包含新旧 ID 的列,然后使用 match
函数,如上面的代码改变了 ids。