将一个矩阵中的每一行与另一个矩阵的每一行进行比较
Comparing every row in one matrix with every row of another matrix
在对矩阵执行处理后(如果需要,可以将其转换为数据框或其他形式),我想查看原始矩阵的行是否出现在新矩阵的任何位置。
E.g.Matrix1=(1,1,1,1,1;
2,2,2,2,2;
3,3,3,4,4;
5,5,5,6,6)
想知道(1,1,1,1,1),(2,2,2,2,2)等是否出现在Matrix2中。我还想知道矩阵 2 中是否出现非常相似的行,例如 (1,1,1,1,8) 或 (2,2,2,2,7)。具体来说,我所说的相似是指它们只有 1 或 2 个列条目不同(对于 11 列,它们有 9 个或更多列条目相同)。
我遇到的主要问题是处理时间,我只有 11 列用于比较矩阵,但是两个矩阵都有大约 200,000 行,所以我将比较 200,000 行和其他 200,000 行。
我有一个带有 for 循环的解决方案,但是 200,000*200,000...
会花费太长时间
#Reproducible Example
Firstmatrix<-t(matrix(c(1,1,1,1,1,
2,2,2,2,2,
3,3,3,3,3,
0,0,0,0,0,
2,2,2,2,2,
4,4,4,4,4,
1,2,3,4,5,
1,1,1,1,6),
nrow=5,ncol=8))
Secondmatrix<-t(matrix(c(1,1,1,1,1,
1,1,1,1,1,
2,2,2,2,2,
3,3,3,3,3,
4,4,4,5,5,
5,5,5,4,4,
6,1,1,1,3,
3,1,1,1,6),
nrow=5,ncol=8))
#these matrices will be in a similar form to example above
#To time test larger matrices with more columns I have used:
Firstmatrix<-Firstmatrix[rep(seq_len(8), each=100),]
Secondmatrix<-Secondmatrix[rep(seq_len(8), each=100),]
#which create matrices with 100x as many rows and
t1<-Sys.time()
t2<-Sys.time()
t2-t1
#either side of the code to measure how long it takes
#I came up with:
Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}
生成一个向量,其中包含 'Firstmatrix' 中每一行的条目,以及它与 'Secondmatrix' 中任何行共有的最大列数,适用于几千行在每个矩阵上,但对于 200k*200k 来说 运行 是不可行的。我知道我可能应该使用 mapply,但不确定如何指定它将对 'Firstmatrix' 的每一行与 'Secondmatrix' 的每一行进行比较。以前的尝试只是将 Firstmatrix 的每个元素与 Secondmatrix 进行比较。
如有任何帮助,我们将不胜感激。我知道这需要大量的计算,所以 运行 总是需要一段时间,但是任何比我当前的代码更快的东西,我认为这需要大约 4 个月,是朝着正确方向迈出的一步!
这应该快得多,因为它只对一组行执行 non-vectorized 迭代,而其余的行被矢量化。这利用了列连续存储的事实,因此 At[, i]
将被适当地回收以执行 ==
操作。另一个好处是获取列可能比获取行更快。
At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
all.equal(mx, c(Maximum.Column.entries.in.common))
## [1] TRUE
时机
这是一个时间比较,显示对于给定的数据,它运行的时间大约是经过时间的 1/60。
system.time({
Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}
})
## user system elapsed
## 10.99 0.00 11.12
system.time({
At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
})
## user system elapsed
## 0.19 0.00 0.19
在对矩阵执行处理后(如果需要,可以将其转换为数据框或其他形式),我想查看原始矩阵的行是否出现在新矩阵的任何位置。
E.g.Matrix1=(1,1,1,1,1;
2,2,2,2,2;
3,3,3,4,4;
5,5,5,6,6)
想知道(1,1,1,1,1),(2,2,2,2,2)等是否出现在Matrix2中。我还想知道矩阵 2 中是否出现非常相似的行,例如 (1,1,1,1,8) 或 (2,2,2,2,7)。具体来说,我所说的相似是指它们只有 1 或 2 个列条目不同(对于 11 列,它们有 9 个或更多列条目相同)。
我遇到的主要问题是处理时间,我只有 11 列用于比较矩阵,但是两个矩阵都有大约 200,000 行,所以我将比较 200,000 行和其他 200,000 行。 我有一个带有 for 循环的解决方案,但是 200,000*200,000...
会花费太长时间#Reproducible Example
Firstmatrix<-t(matrix(c(1,1,1,1,1,
2,2,2,2,2,
3,3,3,3,3,
0,0,0,0,0,
2,2,2,2,2,
4,4,4,4,4,
1,2,3,4,5,
1,1,1,1,6),
nrow=5,ncol=8))
Secondmatrix<-t(matrix(c(1,1,1,1,1,
1,1,1,1,1,
2,2,2,2,2,
3,3,3,3,3,
4,4,4,5,5,
5,5,5,4,4,
6,1,1,1,3,
3,1,1,1,6),
nrow=5,ncol=8))
#these matrices will be in a similar form to example above
#To time test larger matrices with more columns I have used:
Firstmatrix<-Firstmatrix[rep(seq_len(8), each=100),]
Secondmatrix<-Secondmatrix[rep(seq_len(8), each=100),]
#which create matrices with 100x as many rows and
t1<-Sys.time()
t2<-Sys.time()
t2-t1
#either side of the code to measure how long it takes
#I came up with:
Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}
生成一个向量,其中包含 'Firstmatrix' 中每一行的条目,以及它与 'Secondmatrix' 中任何行共有的最大列数,适用于几千行在每个矩阵上,但对于 200k*200k 来说 运行 是不可行的。我知道我可能应该使用 mapply,但不确定如何指定它将对 'Firstmatrix' 的每一行与 'Secondmatrix' 的每一行进行比较。以前的尝试只是将 Firstmatrix 的每个元素与 Secondmatrix 进行比较。
如有任何帮助,我们将不胜感激。我知道这需要大量的计算,所以 运行 总是需要一段时间,但是任何比我当前的代码更快的东西,我认为这需要大约 4 个月,是朝着正确方向迈出的一步!
这应该快得多,因为它只对一组行执行 non-vectorized 迭代,而其余的行被矢量化。这利用了列连续存储的事实,因此 At[, i]
将被适当地回收以执行 ==
操作。另一个好处是获取列可能比获取行更快。
At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
all.equal(mx, c(Maximum.Column.entries.in.common))
## [1] TRUE
时机
这是一个时间比较,显示对于给定的数据,它运行的时间大约是经过时间的 1/60。
system.time({
Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}
})
## user system elapsed
## 10.99 0.00 11.12
system.time({
At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
})
## user system elapsed
## 0.19 0.00 0.19