Прежде всего, попробуйте увеличить вашу оперативную память.
Во-вторых, попробуйте одну из этих функций, используя DenseMatrix в Spark.Обе функции используют одинаковый объем оперативной памяти на моем компьютере.
Я получил 1,34 секунды для анализа строк 201238 в кадре данных с 1 столбцом, каждое из которых содержит несколько значений типа Double:
import org.apache.spark.mllib.linalg.DenseMatrix
import org.apache.spark.ml.linalg.DenseVector
import org.apache.spark.sql.DataFrame
def getDenseMatrixFromDF(featuresDF:DataFrame):DenseMatrix = {
val featuresTrain = featuresDF.columns
val rows = featuresDF.count().toInt
val newFeatureArray:Array[Double] = featuresTrain
.indices
.flatMap(i => featuresDF
.select(featuresTrain(i))
.collect())
.map(r => r.toSeq.toArray).toArray.flatten.flatMap(_.asInstanceOf[org.apache.spark.ml.linalg.DenseVector].values)
val newCols = newFeatureArray.length / rows
val denseMat:DenseMatrix = new DenseMatrix(rows, newCols, newFeatureArray, isTransposed=false)
denseMat
}
ЕслиЯ хочу получить DenseVector из DataFrame с одним столбцом, содержащим только одно значение Double, я получил 0,8 секунды для того же объема данных:
import org.apache.spark.mllib.linalg.DenseVector
import org.apache.spark.ml.linalg.DenseVector
import org.apache.spark.sql.DataFrame
def getDenseVectorFromDF(featuresDF:DataFrame):DenseVector = {
val featuresTrain = featuresDF.columns
val cols = featuresDF.columns.length
cols match {
case i if i>1 => throw new IllegalArgumentException
case _ => {
def addArray(acc:Array[Array[Double]],cur:Array[Double]):Array[Array[Double]] = {
acc :+ cur
}
val newFeatureArray:Array[Double] = featuresTrain
.indices
.flatMap(i => featuresDF
.select(featuresTrain(i))
.collect())
.map(r => r.toSeq.toArray.map(e => e.asInstanceOf[Double])).toArray.flatten
val denseVec:DenseVector = new DenseVector(newFeatureArray)
denseVec
}
}
Чтобы вычислить собственные значения / собственные векторы, просто проверьте эту ссылку и эта ссылка API
Для вычисления ковариационной матрицы chek эта ссылка и эта ссылка API