首页 > 解决方案 > R:缩放 Data.Table 中的每一列

问题描述

我有一个包含 37000 行和 27000 列的 data.table。我想在将数据用于预测任务之前对每一列进行预处理和缩放。

我正在使用这篇文章中提到的方法,但发现它工作得非常缓慢,甚至使 R Studio 崩溃。我附上了下面的方法,供参考。是否有更快的方法来缩放大型 data.table 的所有列?

scale.cols <- colnames(DT)
DT[, (scale.cols) := lapply(.SD, scale), .SDcols = scale.cols]

标签: rdata.table

解决方案


data.table假设您可以首先以矩阵格式获取数据,因为对于大量列来说它不会很快,那么一种可能性是使用RcppArmadillo

scale.cpp

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
arma::mat armaScale(arma::mat Z) {
    unsigned int j, n = Z.n_rows, k = Z.n_cols;
    double avg, sd;
    arma::colvec z;
    arma::mat res = arma::zeros(n, k);

    for (j=0; j<k; j++) {
        z = Z.col(j);
        avg = arma::mean(z);
        sd = arma::stddev(z);
        res.col(j) = (z - avg) / sd;
    }

    return res;
}

代码:

set.seed(0L)
#using a smaller dataset
s <- 2e3
nr <- 3*s
nc <- 2*s
mat <- matrix(rnorm(nr*nc), ncol=nc)

library(RcppArmadillo)
library(Rcpp)
sourceCpp("scale.cpp")

library(microbenchmark)
microbenchmark(armaScale(mat), scale(mat), times=3L)

时间:

Unit: milliseconds
           expr       min        lq      mean    median        uq       max neval cld
 armaScale(mat)  272.4988  290.1339  303.5027  307.7689  319.0047  330.2404     3  a 
     scale(mat) 1290.9581 1400.7916 1445.8927 1510.6251 1523.3600 1536.0950     3   b

推荐阅读