首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取其他向量中向量元素的重复实例的索引(两者都很大)

获取其他向量中向量元素的重复实例的索引(两者都很大)
EN

Stack Overflow用户
提问于 2016-06-19 14:17:46
回答 3查看 286关注 0票数 5

我有两个向量,一个是大约1亿个非唯一元素(整数)的(A),另一个是100万个相同的唯一元素的(B)。我试图得到一个列表,其中包含A中每个B元素的重复实例的索引。

代码语言:javascript
运行
复制
A <- c(2, 1, 1, 1, 2, 1, 1, 3, 3, 2)
B <- 1:3

# would result in this:
[[1]]
[1] 2 3 4 6 7

[[2]]
[1]  1  5 10

[[3]]
[1] 8 9

我首先天真地尝试了这个:

代码语言:javascript
运行
复制
b_indices <- lapply(B, function(b) which(A == b))

这是可怕的低效,显然几年内不会完成。

我尝试的第二件事是创建一个空向量列表,用B的所有元素索引,然后循环遍历A,将索引附加到A中每个元素的对应向量中,尽管技术上是O(n),但我不确定重复添加元素的时间。这种方法显然需要2-3天,但速度还是太慢了.

有什么东西可以更快地工作吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-19 14:33:56

data.table可以说是处理R中大数据的最有效的方法,它甚至可以让您避免将100万长度向量一起使用!

代码语言:javascript
运行
复制
require(data.table)
a <- data.table(x=rep(c("a","b","c"),each=3))
a[ , list( yidx = list(.I) ) , by = x ]

   a  yidx
1: a 1,2,3
2: b 4,5,6
3: c 7,8,9

使用示例数据:

代码语言:javascript
运行
复制
a <- data.table(x=c(2, 1, 1, 1, 2, 1, 1, 3, 3, 2))
a[ , list( yidx = list(.I) ) , by = x ]

   a      yidx
1: 2   1, 5,10
2: 1 2,3,4,6,7
3: 3       8,9

将其添加到基准测试中。我敢说,如果你在规模上测试它,它应该比使用内置函数要快得多。在我的经验中,数据越大,data.table的相对性能就越好。

在我的基准order中,在Debian笔记本电脑上只需要46%的,而在带有2.x GHz CPU的Windows笔记本电脑上,只需要的5%。

代码语言:javascript
运行
复制
B <- seq_len(1e6)
set.seed(42)
A <- data.table(x = sample(B, 1e8, TRUE))
system.time({
+   res <- A[ , list( yidx = list(.I) ) , by = x ]
+ })
   user  system elapsed 
   4.25    0.22    4.50 
票数 6
EN

Stack Overflow用户

发布于 2016-06-19 14:34:09

这是快速的:

代码语言:javascript
运行
复制
A1 <- order(A, method = "radix")

split(A1, A[A1])
#$`1`
#[1] 2 3 4 6 7
#
#$`2`
#[1]  1  5 10
#
#$`3`
#[1] 8 9

B <- seq_len(1e6)
set.seed(42)
A <- sample(B, 1e8, TRUE)

system.time({
  A1 <- order(A, method = "radix")

  res <- split(A1, A[A1])
})
# user      system     elapsed 
#8.650       1.056       9.704
票数 8
EN

Stack Overflow用户

发布于 2016-06-19 14:42:56

我们也可以使用dplyr

代码语言:javascript
运行
复制
library(dplyr)
data_frame(A) %>% 
      mutate(B = row_number()) %>%
      group_by(A) %>%
      summarise(B = list(B)) %>% 
      .$B

#[[1]]
#[1] 2 3 4 6 7

#[[2]]
#[1]  1  5 10

#[[3]]
#[1] 8 9

在1e5大小的较小数据集中,它给出了system.time

代码语言:javascript
运行
复制
#   user  system elapsed 
#   0.01    0.00    0.02 

但在另一篇文章中显示的更大的例子中,它要慢一些。然而,这是dplyr..。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37908178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档