计算R中一个大矩阵的行和?
我有一个大矩阵,大约有6000万行和150列(大约总共90亿个元素)。我已将此数据存储在一个计算R中一个大矩阵的行和?,r,bigdata,r-bigmemory,R,Bigdata,R Bigmemory,我有一个大矩阵,大约有6000万行和150列(大约总共90亿个元素)。我已将此数据存储在一个big.matrix对象中(来自packagebigmemory)。现在,我想计算每一行的总和,这是一个问题,因为big.matrix是面向列的,所以据我所知,所有汇总函数都是面向列的(例如colsum,colmax,等等),默认情况下没有用于计算行总和的函数。当然我可以做应用(x,1,sum),但这需要很长时间。我还可以逐个循环列,并使用矢量化加法添加它们: mysum <- rep(0, nro
big.matrix
对象中(来自packagebigmemory
)。现在,我想计算每一行的总和,这是一个问题,因为big.matrix
是面向列的,所以据我所知,所有汇总函数都是面向列的(例如colsum
,colmax
,等等),默认情况下没有用于计算行总和的函数。当然我可以做应用(x,1,sum)
,但这需要很长时间。我还可以逐个循环列,并使用矢量化加法添加它们:
mysum <- rep(0, nrow(x))
for (i in seq(ncol(x)))
mysum <- mysum + x[,i]
<代码> MySoo> p>我编写了一些C++代码来完成这一操作,从: rowSums.cpp
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <numeric>
// Logic for BigRowSums.
template <typename T>
NumericVector BigRowSums(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat) {
NumericVector rowSums(pMat->nrow(), 0.0);
NumericVector value(1);
for (int jj = 0; jj < pMat->ncol(); jj++) {
for (int ii = 0; ii < pMat->nrow(); ii++) {
value = mat[jj][ii];
if (all(!is_na(value))) {
rowSums[ii] += value[0];
}
}
}
return rowSums;
}
// Dispatch function for BigRowSums
//
// [[Rcpp::export]]
NumericVector BigRowSums(SEXP pBigMat) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1:
return BigRowSums(xpMat, MatrixAccessor<char>(*xpMat));
case 2:
return BigRowSums(xpMat, MatrixAccessor<short>(*xpMat));
case 4:
return BigRowSums(xpMat, MatrixAccessor<int>(*xpMat));
case 6:
return BigRowSums(xpMat, MatrixAccessor<float>(*xpMat));
case 8:
return BigRowSums(xpMat, MatrixAccessor<double>(*xpMat));
default:
throw Rcpp::exception("unknown type detected for big.matrix object!");
}
}
/[[Rcpp::depends(BH)]]
#包括
使用名称空间Rcpp;
//[[Rcpp::Dependes(BH,bigmemory)]]
#包括
#包括
//大行和的逻辑。
模板
数字向量大行和(XPtr pMat,MatrixAccessor mat){
数值向量行和(pMat->nrow(),0.0);
数值向量值(1);
对于(intjj=0;jjncol();jj++){
对于(int ii=0;iinrow();ii++){
价值=材料[jj][ii];
如果(全部(!为_na(值))){
行和[ii]+=值[0];
}
}
}
返回行和;
}
//大行和的调度函数
//
//[[Rcpp::导出]]
数字向量BigRowSums(SEXP-pBigMat){
XPtr xpMat(pBigMat);
开关(xpMat->matrix_type()){
案例1:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例2:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例4:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例6:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
案例8:
返回BigRowSums(xpMat,MatrixAccessor(*xpMat));
违约:
抛出Rcpp::异常(“为big.matrix对象检测到未知类型!”);
}
}
在R:
library(bigmemory)
library(Rcpp)
sourceCpp("rowSums.cpp")
m <- as.big.matrix(matrix(1:9, 3))
BigRowSums(m@address)
[1] 12 15 18
库(大内存)
图书馆(Rcpp)
sourceCpp(“rowSums.cpp”)
mrowSums
对它不起作用吗?您可以转置然后获取colsum
吗?假设您有数字
数据,您所指示的时间对应于大约60 MB/s的吞吐量(20分钟内72 GB数据=3.6 GB/min)。根据数据存储的位置,这可能非常接近物理限制。读取该文件需要多长时间(time cp file>/dev/null
)?它不是R的数字类型。它是一个大的整数矩阵,所以我相信它在磁盘和内存中都存储得更紧凑。磁盘上的文件大约是30GB,我不知道当我加载它时,它是否会将整个矩阵加载到内存中。您不能一次对整个内容进行操作,因为其中包含的元素多于.Machine$integer.max
元素。这就是为什么我把它放在一个大的.matrix
中。您无法快速转换大.matrix
。正如我所说,数据结构是面向列的,因此转置它必须完全重建整个数据结构。您可以随时修改Rcpp
库中的代码,以执行rowSums
,而不是colSums
:这看起来很棒。如果它比我已经得到的(可能是)快,我会接受它作为答案。我曾尝试创建一个文件备份的大矩阵来测试它,但它使我的计算机停止运行(创建它),所以我杀死了它。我很想看看情况如何!你不能用艾根或犰狳吗?我认为即使在C++中,这样的嵌套循环也会非常快。