Scala: ¿cómo obtener la media, la varianza y la covarianza de una matriz?
Soy nuevo en scala y necesito desesperadamente orientación sobre el siguiente problema:
Tengo un dataframe como el siguiente (algunos elementos pueden ser NULL)
“`
val dfDouble = Seq(
(1.0, 1.0, 1.0, 3.0),
(1.0, 2.0, 0.0, 0.0),
(1.0, 3.0, 1.0, 1.0),
(1.0, 4.0, 0.0, 2.0)).toDF("m1", "m2", "m3", "m4")
dfDouble.show
+—+—+—+—+
| m1| m2| m3| m4|
+—+—+—+—+
|1.0|1.0|1.0|3.0|
|1.0|2.0|0.0|0.0|
|1.0|3.0|1.0|1.0|
|1.0|4.0|0.0|2.0|
+—+—+—+—+
“`
Necesito obtener las siguientes estadísticas de este dataframe:
1) un vector que contenga la media de cada columna (algunos elementos pueden ser NULL y quiero calcular la media usando solo los elementos no nulos); También me gustaría referirme a cada elemento del vector por nombre, por ejemplo, vecmean[“m1mean”] devolvería el primer elemento
vec_mean: Vector(m1_mean, m2_mean, m3_mean, m4_mean)
2) una matriz de varianza-covarianza que sea (4 x 4), donde la diagonal son var(m1), var(m2),...,
y los off-diagonales son cov(m1,m2), cov(m1,m3) ...
Aquí también me gustaría usar solo los elementos no nulos en el cálculo de varianza-covarianza
3) Un vector que contenga el número de valores no nulos para cada columna
vec_n: Vector(m1_n, m2_n, m3_n, m4_n)
4) Un vector que contenga la desviación estándar de cada columna
vec_stdev: Vector(m1_stde, m2_stde, m3_stde, m4_stde)
En R convertiría todo a una matriz y luego el resto es fácil. Pero en scala, no estoy familiarizado con las matrices y aparentemente hay varios tipos de matrices, lo cual es confuso (DenseMatrix, IndexedMatrix, etc.)
Editado: aparentemente hay una diferencia si el contenido del dataframe es Double o Int. Revisé los elementos para que sean double
Usé el siguiente comando según la respuesta sugerida y funcionó!
val rdd = dfDouble0.rdd.map {
case a: Row => (0 until a.length).foldRight(ArrayDouble)((b, acc) =>
{ val k = a.getAsDouble
if(k == null)
acc.+:(0.0)
else acc.+:(k)}).map(_.toDouble)
}
davy.ai
Para lograr los resultados deseados, podemos usar las funciones proporcionadas por el paquete
org.apache.spark.mllib.linalg
. Aquí está el código para realizar las tareas mencionadas:Salida:
Con respecto a los diferentes tipos de matrices,
DenseMatrix
es una matriz densa donde todos los elementos se almacenan en un solo bloque de memoria, lo que la hace eficiente cuando el tamaño de la matriz no es muy grande. Por otro lado,IndexedRowMatrix
yCoordinateMatrix
son más adecuados para datos dispersos, donde la mayoría de los valores son cero. Dado que nuestros datos son densos, usarDenseMatrix
es suficiente.