如何调用Spark中的数据标准化库

在大数据的学习过程中,总有很多小伙伴遇到不知如何调用Spark中的数据标准库,本文的核心这不是在于介绍「数据标准化」,也不是在于实现「Spark调用」,毕竟这些概念大家应该耳濡目染了,至于调用方法一搜一大堆。今天这个问题也是科多大数据的一名学员提出来的,估计有很多人也遇到类似的问题,一并分享在此,希望可以帮到大家。

首先,我们先看一下Spark要做「标准化」的输入数据样式。

// 原始数据

+---+-----------------+

| id|  features  |

+---+-----------------+

| 0 |[1.0,0.5,-1.0]|

| 1 | [2.0,1.0,1.0]|

| 2 |[4.0,10.0,2.0]|

+---+-----------------+

看到这,我就不想去用了,除了简单的DataFrame赋值,正常情况下的业务特征都是一张宽表,或者是其他特征工程的组合形式。

那有人会无聊去把数据的存储形式保存为向量型的呢?虽然也可以这样做,但是我觉得不太方便去回顾数据。

其次,在无奈之下,我在使用DataFrame和「标准化库」时,做了一个简单的优化,具体如下所示:

// 原始数据

Userid,Feature1,Feature2,Feature3

import sqlContext.implicits._

//需要进行数据标准化的特征(除Userid外)有:

val value = behavData.map(_.split(",")).map(record =>

{

var featureArray:Array[Double] = new Array[Double](3)

        val userid = record(0)

        val feature = ( for(i <- 1 until 3 ) yield record(i).toDouble ).toArray

        val featureVector = Vectors.dense(feature)

        (userid,featureVector)

}

).toDF("userid","featureSet")

这样的话,我就可以直接将「原始数据」转化为Spark标准化库所要求的样式了。

// 转化数据

Userid,[Feature1,Feature2,Feature3]

提醒一下,其他向量类型还不行,必须是import org.apache.spark.mllib.linalg.Vectors;

令人反感的「数据输入」解决了一半,我们再着手「数据输出」,尽量让后期的建模工作顺畅起来。

// 这是其中一种标准化方法的数据输出。

+------+----------------------+-------------------------------------------------------------------+

| id  |  features     |           scaledFeatures                  |

+------+-----------------------+------------------------------------------------------------------+

| 0  |  [1.0,0.5,-1.0]  |  [0.654653670707,0.09352195,-0.654653670]  |

| 1  |  [2.0,1.0,1.0]   |  [1.3093073414159544,0.18704390,0.65465]  |

| 2  |  [4.0,10.0,2.0]  |  [2.618614682831909,1.87043905,1.309307]  |

+-----+-------------------------+-----------------------------------------------------------------+

可能是我真的看不习惯,要说这结果输出的灵活性太差也不为过,所以我又做了一个简单的优化。

//将DataFrame转换成RDD再存储于HDFS上

val resultRDD = inputValue.rdd.map(record =>

{

val ouputResult = new StringBuilder()

        ouputResult.append(record(0).toString()).append(",")

//调用字符串StrDealOne函数

StrDealOne(record(1).toString()).split(",").map(records =>

{

ouputResult.append(round(records.toDouble,4)).append(",")

}

)

        //调用字符串StrDealTwo函数

        StrDealTwo(ouputResult.toString())

}

)

其中

/**

* 字符串处理(替换特殊字符、去掉字符串末尾一位)

*/

def StrDealOne(InputValue:String):String = {

InputValue.replaceAll("\\(","").replaceAll("\\)","").replaceAll("\\[","").replaceAll("\\]","")

}

  def StrDealTwo(InputValue:String):String = {

InputValue.substring(0, InputValue.toString().length()-1)

}

简单来说,就是让标准化后的数据恢复最初的Userid,Feature1,Feature2,Feature3格式,方便后期使用。

通过对数据「输入」和「输出」的简单操作,我在后期想将数值型的特征进行标准化时,就能很舒服去调用了。

通过以上的方法,就能轻松的调用Spark中的数据标准化库了

猜你喜欢

转载自blog.csdn.net/weixin_41852491/article/details/83095534