gpt4 book ai didi

r - 从 data.frame 中提取列比从矩阵中提取列更快 - 为什么?

转载 作者:行者123 更新时间:2023-12-01 12:09:01 25 4
gpt4 key购买 nike

我正在运行一个模拟,我需要从矩阵中重复提取 1 列,并根据某些条件(例如 < 10)检查它的每个值。但是,使用矩阵执行此操作比使用 data.frame 执行相同操作慢 3 倍。为什么会这样?

我想使用矩阵来存储模拟数据,因为它们对于某些其他操作(例如,通过添加/减去值来更新列)更快。如何以更快的方式提取列/子集矩阵?

从 data.frame 与矩阵中提取列:

df <- data.frame(a = 1:1e4)
m <- as.matrix(df)

library(microbenchmark)
microbenchmark(
df$a,
m[ , "a"])

# Results; Unit: microseconds
# expr min lq mean median uq max neval cld
# df$a 5.463 5.8315 8.03997 6.612 8.0275 57.637 100 a
# m[ , "a"] 64.699 66.6265 72.43631 73.759 75.5595 117.922 100 b

从 data.frame 与矩阵中提取单个值:

microbenchmark(
df[1, 1],
df$a[1],
m[1, 1],
m[ , "a"][1])

# Results; Unit: nanoseconds
# expr min lq mean median uq max neval cld
# df[1, 1] 8248 8753.0 10198.56 9818.5 10689.5 48159 100 c
# df$a[1] 4072 4416.0 5247.67 5057.5 5754.5 17993 100 b
# m[1, 1] 517 708.5 828.04 810.0 920.5 2732 100 a
# m[ , "a"][1] 45745 47884.0 51861.90 49100.5 54831.5 105323 100 d

我预计矩阵列提取会更快,但速度更慢。但是,从矩阵中提取单个值(即 m[1, 1])比使用 data.frame 的两种方法都快。我不知道为什么会这样。

提取行与列,data.frame 与矩阵:

以上仅适用于选择列。选择行时,矩阵比 data.frames 快得多。仍然不知道为什么。

microbenchmark(
df[1, ],
m[1, ],
df[ , 1],
m[ , 1])

# Result: Unit: nanoseconds
# expr min lq mean median uq max neval cld
# df[1, ] 16359 17243.5 18766.93 17860.5 19849.5 42973 100 c
# m[1, ] 718 999.5 1175.95 1181.0 1327.0 3595 100 a
# df[ , 1] 7664 8687.5 9888.57 9301.0 10535.5 42312 100 b
# m[ , 1] 64874 66218.5 72074.93 73717.5 74084.5 97827 100 d

最佳答案

数据框

考虑内置数据框BOD。数据帧存储为列列表,下面显示的 inspect 输出显示了 BOD 两列中每一列的地址。然后我们将其第二列分配给 BOD2。请注意,BOD2 的地址与 inspectBOD 输出中显示的第二列内存位置相同。也就是说,R 所做的只是让 BOD2 指向 BOD 中的内存,以便创建 BOD2。根本没有数据移动。另一种查看方式是比较 BODBOD2 和两者的大小,我们看到它们一起占用的内存量与 BOD 所以一定没有复制。 (在代码之后继续。)

library(pryr)

BOD2 <- BOD[[2]]
inspect(BOD)
## <VECSXP 0x507c278>
## <REALSXP 0x4f81f48>
## <REALSXP 0x4f81ed8> <--- compare this address to address shown below
## ...snip...

BOD2 <- BOD[,2]
address(BOD2)
## [1] "0x4f81ed8"

object_size(BOD)
## 1.18 kB
object_size(BOD2)
## 96 B
object_size(BOD, BOD2) # same as object_size(BOD) above
## 1.18 kB

矩阵

矩阵存储为一个具有维度的长向量而不是列列表,因此提取列的策略是不同的。如果我们查看矩阵 m、提取的列 m2 以及两者一起使用的内存,我们会在下面看到它们一起使用显示的各个对象的内存总和有数据复制。

set.seed(123)

n <- 10000L
m <- matrix(rnorm(2*n), n, 2)
m2 <- m[, 2]

object_size(m)
## 160 kB
object_size(m2)
## 80 kB
object_size(m, m2)
## 240 kB <-- unlike for data.frames this equals sum of above

做什么

如果您的程序只在某个点使用列提取,您可以对该部分使用数据框,然后一次性转换为矩阵并像处理其余部分一样处理它。

关于r - 从 data.frame 中提取列比从矩阵中提取列更快 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54005918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com