给出微风SparseVector
对象:
scala> val sv = new SparseVector[Double](Array(0, 4, 5), Array(1.5, 3.6, 0.4), 8)
sv: breeze.linalg.SparseVector[Double] = SparseVector(8)((0,1.5), (4,3.6), (5,0.4))
获取值+ 1的对数的最佳方法是什么?
这是一种有效的方法:
scala> new SparseVector(sv.index, log(sv.data.map(_ + 1)), sv.length)
res11: breeze.linalg.SparseVector[Double] = SparseVector(8)((0,0.9162907318741551), (4,1.5260563034950492), (5,0.3364722366212129))
我不喜欢这样,因为它并没有真正利用微风进行添加。我们正在使用微妙的UFunc来获取Array [Double]的日志,但这并不多。我担心在具有大型SparseVectors的分布式应用程序中,这会很慢。
答案 0 :(得分:0)
您可以定义一些UDF在Spark中进行任意矢量化加法。首先,您需要设置将Spark向量转换为Breeze向量的功能;这样做的一个例子是here。进行隐式转换后,您将有一些选择。
要添加任何两列,您可以使用:
def addVectors(v1Col: String, v2Col: String, outputCol: String): DataFrame => DataFrame = {
// Error checking column names here
df: DataFrame => {
def add(v1: SparkVector, v2: SparkVector): SparkVector =
(v1.asBreeze + v2.asBreeze).fromBreeze
val func = udf((v1: SparkVector, v2: SparkVector) => add(v1, v2))
df.withColumn(outputCol, func(col(v1Col), col(v2Col)))
}
}
请注意,上面链接的问题中确定了对asBreeze
和fromBreeze
(以及SparkVector
的别名)的使用。一种可能的解决方案是使用
df.withColumn(colName, lit(1))
然后添加列。
更复杂的数学函数的替代方法是:
def applyMath(func: BreezeVector[Double] => BreezeVector[Double],
inColName: String, outColName: String): DataFrame => DataFrame = {
df: DataFrame => df.withColumn(outColName,
udf((v1: SparkVector) => func(v1.asBreeze).fromBreeze).apply(col(inColName)))
}
您也可以在Breeze矢量参数中将此名称设为通用。