gpt4 book ai didi

r - 查找匹配行的最快方法

转载 作者:行者123 更新时间:2023-12-04 03:11:10 25 4
gpt4 key购买 nike

我想知道在xts对象中查找与某一特定行相同的所有行的最快方法是什么

library(xts)

nRows <- 3

coreData <- data.frame(a=rnorm(nRows), b=rnorm(nRows), c=rnorm(nRows))

testXts1 <- xts(coreData, order.by=as.Date(1:nRows))
testXts2 <- xts(coreData, order.by=as.Date((nRows + 1):(2*nRows)))
testXts3 <- xts(coreData, order.by=as.Date((2*nRows + 1):(3*nRows)))

testXts <- rbind(testXts1, testXts2, testXts3)

> testXts
a b c
1970-01-02 -0.3288756 1.441799 1.321608
1970-01-03 -0.7105016 1.639239 -2.056861
1970-01-04 0.1138675 -1.782825 -1.081799
1970-01-05 -0.3288756 1.441799 1.321608
1970-01-06 -0.7105016 1.639239 -2.056861
1970-01-07 0.1138675 -1.782825 -1.081799
1970-01-08 -0.3288756 1.441799 1.321608
1970-01-09 -0.7105016 1.639239 -2.056861
1970-01-10 0.1138675 -1.782825 -1.081799

rowToSearch <- first(testXts)

> rowToSearch
a b c
1970-01-02 -0.3288756 1.441799 1.321608

indicesOfMatchingRows <- unlist(apply(testXts, 1, function(row) lapply(1:NCOL(row), function(i) row[i] == coredata(rowToSearch[, i]))))

testXts[indicesOfMatchingRows, ]

a b c
1970-01-02 -0.3288756 1.441799 1.321608
1970-01-05 -0.3288756 1.441799 1.321608
1970-01-08 -0.3288756 1.441799 1.321608

我相信这可以用更优雅,更快捷的方式来完成。

一个更笼统的问题是您在R中怎么说:“我有此行matrix [5,],如何在矩阵中找到与matrix [5,]相同的其他行(的索引)”。

如何在 data.table中做到这一点?

最佳答案

既然您说速度是您的主要关注点,那么使用Rcpp甚至可以通过data.table解决方案来提高速度:

library(Rcpp)
cppFunction(
"LogicalVector compareToRow(NumericMatrix x, NumericVector y) {
const int nr = x.nrow();
const int nc = x.ncol();
LogicalVector ret(nr, true);
for (int j=0; j < nr; ++j) {
for (int k=0; k < nc; ++k) {
if (x(j, k) != y[k]) {
ret[j] = false;
break;
}
}
}
return ret;
}")
testXts[compareToRow(testXts, rowToSearch),]
# a b c
# 1970-01-02 1.324457 0.8485654 -1.464764
# 1970-01-05 1.324457 0.8485654 -1.464764
# 1970-01-08 1.324457 0.8485654 -1.464764

这是一个相当大的实例(具有一百万行)的比较:
set.seed(144)
bigXts <- testXts[sample(nrow(testXts), 1000000, replace=TRUE),]
testDT <- as.data.frame(bigXts)

josilber <- function(x, y) x[compareToRow(x, y),]
roland.base <- function(x, y) x[colSums(t(x) != as.vector(y)) == 0L,]
library(data.table)
roland.dt <- function(testDT, y) {
setDT(testDT, keep.rownames=TRUE)
setkey(testDT, a, b, c)
testDT[setDT(as.data.frame(y))]
}
library(microbenchmark)
microbenchmark(josilber(bigXts, rowToSearch), roland.base(bigXts, rowToSearch), roland.dt(testDT, rowToSearch), times=10)
# Unit: milliseconds
# expr min lq mean median uq max
# josilber(bigXts, rowToSearch) 7.830986 10.24748 45.64805 14.41775 17.37049 258.4404
# roland.base(bigXts, rowToSearch) 3530.042324 3964.72314 4288.05758 4179.64233 4534.21407 5400.5619
# roland.dt(testDT, rowToSearch) 32.826285 34.95014 102.52362 57.30213 130.51053 267.2249

此基准测试假设在调用 roland.dt之前已将对象转换为数据帧(约4秒的开销),并且在调用 compareToRows之前已将 josilber编译(约3秒的开销)。在中值运行时中,Rcpp解决方案的速度比基本R解决方案快300倍,比data.table解决方案快4倍。基于 digest的方法并不具有竞争力,每次执行都需要60秒钟以上的时间。

关于r - 查找匹配行的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30955790/

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