spark DenseVector原理示例源码分析
原理
DenseVector
类是Spark中表示稠密向量的一种数据结构。它使用一个值数组来存储向量的元素。
方法总结
构造函数:
DenseVector(values: Array[Double])
:构造一个稠密向量,使用给定的值数组作为参数。
函数:
size: Int
:返回向量的大小。toString: String
:返回向量的字符串表示形式。toArray: Array[Double]
:将向量转换为值数组。asBreeze: BV[Double]
:将向量转换为Breeze库中的向量。apply(i: Int): Double
:获取指定索引处的元素值。copy: DenseVector
:复制向量,返回新的DenseVector
实例。foreachActive(f: (Int, Double) => Unit): Unit
:对向量中的每个非零元素执行指定的操作。equals(other: Any): Boolean
:判断向量是否与另一个对象相等。hashCode(): Int
:计算向量的哈希码。numActives: Int
:返回向量中非零元素的数量。numNonzeros: Int
:返回向量中非零元素的数量。toSparseWithSize(nnz: Int): SparseVector
:将稠密向量转换为稀疏向量。argmax: Int
:返回向量中最大元素的索引。
伴生对象函数:
unapply(dv: DenseVector): Option[Array[Double]]
:从DenseVector
实例中提取值数组。
这些函数使得你可以操作稠密向量,包括构造向量、访问元素、遍历元素、比较向量、转换为其他类型的向量等。
示例说明
以下是DenseVector
类的所有public方法和功能的示例:
// size方法:返回向量的大小
val size: Int = vector.size
// toString方法:返回向量的字符串表示形式
val str: String = vector.toString
// toArray方法:将向量转换为值数组
val array: Array[Double] = vector.toArray
// apply方法:获取指定索引处的元素值
val element: Double = vector(2)
// copy方法:复制向量,返回新的DenseVector实例
val copiedVector: DenseVector = vector.copy
// foreachActive方法:对向量中的每个非零元素执行指定的操作
vector.foreachActive((index, value) => println(s"Index: $index, Value: $value"))
// equals方法:判断向量是否与另一个对象相等
val otherVector = new DenseVector(Array(1.0, 2.0, 3.0, 4.0, 5.0))
val isEqual: Boolean = vector.equals(otherVector)
// hashCode方法:计算向量的哈希码
val hashCode: Int = vector.hashCode()
// numActives方法:返回向量中非零元素的数量
val numActives: Int = vector.numActives
// numNonzeros方法:返回向量中非零元素的数量
val numNonzeros: Int = vector.numNonzeros
// argmax方法:返回向量中最大元素的索引
val maxIndex: Int = vector.argmax
// unapply方法:从DenseVector实例中提取值数组
val DenseVector(valuesArray) = vector
以上示例涵盖了DenseVector
类的所有方法和功能。
中文源码
/**
* 由值数组表示的稠密向量。
*/
@Since("2.0.0")
class DenseVector @Since("2.0.0") ( @Since("2.0.0") val values: Array[Double]) extends Vector {
override def size: Int = values.length
override def toString: String = values.mkString("[", ",", "]")
override def toArray: Array[Double] = values
private[spark] override def asBreeze: BV[Double] = new BDV[Double](values)
override def apply(i: Int): Double = values(i)
override def copy: DenseVector = {
new DenseVector(values.clone())
}
override def foreachActive(f: (Int, Double) => Unit): Unit = {
var i = 0
val localValuesSize = values.length
val localValues = values
while (i < localValuesSize) {
f(i, localValues(i))
i += 1
}
}
override def equals(other: Any): Boolean = super.equals(other)
override def hashCode(): Int = {
var result: Int = 31 + size
var i = 0
val end = values.length
var nnz = 0
while (i < end && nnz < Vectors.MAX_HASH_NNZ) {
val v = values(i)
if (v != 0.0) {
result = 31 * result + i
val bits = java.lang.Double.doubleToLongBits(values(i))
result = 31 * result + (bits ^ (bits >>> 32)).toInt
nnz += 1
}
i += 1
}
result
}
override def numActives: Int = size
override def numNonzeros: Int = {
// 与 values.count(_ != 0.0) 相同,但更快
var nnz = 0
values.foreach { v =>
if (v != 0.0) {
nnz += 1
}
}
nnz
}
private[linalg] override def toSparseWithSize(nnz: Int): SparseVector = {
val ii = new Array[Int](nnz)
val vv = new Array[Double](nnz)
var k = 0
foreachActive { (i, v) =>
if (v != 0) {
ii(k) = i
vv(k) = v
k += 1
}
}
new SparseVector(size, ii, vv)
}
override def argmax: Int = {
if (size == 0) {
-1
} else {
var maxIdx = 0
var maxValue = values(0)
var i = 1
while (i < size) {
if (values(i) > maxValue) {
maxIdx = i
maxValue = values(i)
}
i += 1
}
maxIdx
}
}
}
@Since("2.0.0")
object DenseVector {
/** 从稠密向量中提取值数组。 */
@Since("2.0.0")
def unapply(dv: DenseVector): Option[Array[Double]] = Some(dv.values)
}
dx
}
}
}
@Since(“2.0.0”)
object DenseVector {
/** 从稠密向量中提取值数组。 */
@Since(“2.0.0”)
def unapply(dv: DenseVector): Option[Array[Double]] = Some(dv.values)
}