e.g。
a1 <- rbind(c(1,3), c(1,2))
A1 <- rbind(c(1, 2), c(1, 4), c(1,3), c(2, 4))
我想检查A1中哪一行的a1。 在此示例中,返回值应为c(3,1)。
答案 0 :(得分:2)
对于不测试早期解决方案,我深表歉意,我希望这对您有用:
options(stringsAsFactors =F)
a11 <- do.call("paste0",data.frame(a1))
A11 <- do.call("paste0", data.frame(A1))
which(A11 %in% a11)
<强>输出强>:
> a11
[1] "13" "12"
> A11
[1] "12" "14" "13" "24"
> which(A11 %in% a11)
[1] 1 3
答案 1 :(得分:1)
使用apply
和duplicated
的解决方案。我们的想法是使用apply
循环遍历A1
中的每一行,每行rbind
为a1
,使用duplicated
和{{1}检查是否有任何重复。
any
或者我们可以将所有数字组合成字符串并匹配which(apply(A1, 1, function(x) any(duplicated(rbind(x, a1)))))
# [1] 1 3
和A1
中的字符串。该解决方案的灵感来自PKumar的解决方案。
a1
在Dror Bogin的回答的评论部分,OP提出了一个解决方案,即which(apply(A1, 1, toString) %in% apply(a1, 1, toString))
# [1] 1 3
。只有在大矩阵中没有重复项时,此解决方案才有效,例如which(duplicated(rbind(a1 ,A1))) - nrow(a1)
。
例如,考虑以下矩阵A1
,它与A2
相同,除了三个额外的行,其中两个是重复的。
A1
A2 <- rbind(c(1, 2), c(1, 4), c(1, 3), c(2, 4), c(5, 8), c(4, 3), c(5, 8))
的预期输出也应为A2
。但是,当我们使用OP的解决方案时,我们将获得7的额外索引。
c(1, 3)
但我的解决方案仍会返回which(duplicated(rbind(a1 ,A2)))-nrow(a1)
# [1] 1 3 7
。
c(1, 3)
最后,如果OP确定没有任何重复。我们可以使用以下代码来进一步简化代码。
which(apply(A2, 1, function(x) any(duplicated(rbind(x, a1)))))
# [1] 1 3
由于OP提到现实矩阵很大,所以值得对这里提出的所有方法进行性能评估。
到目前为止,我们总共有五种方法。
方法1:我提出的“应用复制”方法。
方法2:受PKumar启发的“apply-toString-match”方法
方法3:PKumar提出的“do.call-dataframe-match”方法
方法4:Dror Bogin提出的“for-loop”方法
方法5:提出了“data.table”方法tophcito
下面我使用which(duplicated(rbind(A1, a1), fromLast = TRUE))
# [1] 1 3
包进行效果评估。
microbenchmark
结果表明,方法2是最快的,方法3是第二快的。有意义的是,方法2应该比方法3更快,因为将对象从矩阵转换为数据帧需要一些时间。方法1排名第三,在我看来仍然被认为是一种表现良好的方法。方法5比上述三种方法慢,表明尽管library(microbenchmark)
library(data.table)
microbenchmark(m1 = {which(apply(A1, 1, function(x) any(duplicated(rbind(x, a1)))))},
m2 = {which(apply(A1, 1, toString) %in% apply(a1, 1, toString))},
m3 = {which(do.call("paste0",data.frame(A1)) %in% do.call("paste0",data.frame(a1)))},
m4 = {v1 = vector()
for(i in 1:nrow(A1)){
b = ifelse(all(a1[1,] == A1[i,]),i,NA)
d = ifelse(all(a1[2,] == A1[i,]),i,NA)
v1 = c(v1,b,d)
}
v1[!is.na(v1)]},
m5 = {a1_dt <- as.data.table(as.data.frame(a1))
A1_dt <- as.data.table(as.data.frame(A1))
setnames(a1_dt, c("x", "y"))
setnames(A1_dt, c("x", "y"))
A1_dt[, id := 1:nrow(A1_dt)]
result <- merge(A1_dt, a1_dt, by = c("x", "y"))
result[, id]})
# Unit: microseconds
# expr min lq mean median uq max neval
# m1 164.498 191.7435 235.6025 215.1320 237.751 1777.094 100
# m2 71.968 82.2490 101.0790 99.2130 112.064 202.024 100
# m3 140.851 165.5265 197.3618 185.3175 206.908 395.824 100
# m4 4734.462 5107.4095 5450.1260 5348.2450 5535.876 8807.847 100
# m5 1286.684 1394.6360 1591.3651 1508.7560 1674.283 4361.256 100
设计用于处理大数据帧,但在这种情况下,不需要使用data.table
进行操作。最后,方法4是最慢的,在这种情况下显示for循环是低效的。
答案 2 :(得分:0)
您必须为 a1 中要检查的每一行添加变量:
Wn = float(1)/HalfSampling
b, a = signal.butter(3, Wn, 'high', analog=False)
BxHPF = signal.filtfilt(b, a, Bxfft)
ByHPF = signal.filtfilt(b, a, Byfft)
plt.plot(BxTime, BxHPF, label='Canal 1', color='r', linewidth=0.5, linestyle="-")
plt.plot(ByTime, ByHPF, label='Canal 3', color='b', linewidth=0.5, linestyle="-")
答案 3 :(得分:0)
使用%in%
和rowSums
的解决方案(应该是改进它的方法):
apply(a1, 1,
function(x) which(rowSums(matrix(A1 %in% x, ncol = 2)) == 2))
另一种可能性是使用rowMeans
和== 1
答案 4 :(得分:0)
可能的解决方案需要添加行号并将两个矩阵合并为数据表。优点是数据表针对速度和大数据进行了优化。
首先,将两个矩阵转换为数据表:
library(data.table)
a1 <- as.data.table(as.data.frame(a1))
A1 <- as.data.table(as.data.frame(A1))
setnames(a1, c("x", "y"))
setnames(A1, c("x", "y"))
让我们添加一个带有rownumbers的附加列:
A1[, id := 1:nrow(A1)]
最后,我们合并了两个表(它们将返回A1
的行,其中a1
的值出现在其中:
result <- merge(A1, a1, by = c("x", "y"))
由于您只对行号感兴趣,因此请选择:
result[, id]