spark开发问题汇总 (持续更新20210604)

Spark官方文档:http://spark.apache.org/docs/2.1.0/index.html
Spark2.0新特性介绍:http://www.slideshare.net/databricks/apache-spark-20-faster-easier-and-smarter
Spark2.0和Spark1.6性能对比:https://databricks.com/blog/2016/05/11/apache-spark-2-0-technical-preview-easier-faster-and-smarter.html

下面这个博客介绍的基本算子比较全面且带有例子,故不重复撰写
spark算子详解------spark算子分类
spark算子详解------Transformation算子介绍
spark算子详解------Action算子介绍

文章目录

一、两个同类型的rdd合并

union(ortherDataset):将两个RDD中的数据集进行合并,最终返回两个RDD的并集,若RDD中存在相同的元素也不会去重

//省略sc
   val rdd1 = sc.parallelize(1 to 3)
   val rdd2 = sc.parallelize(3 to 5)
   val unionRDD = rdd1.union(rdd2)
   unionRDD.collect.foreach(x => print(x + " "))
   sc.stop 

输出:

1 2 3 3 4 5

Spark函数详解系列之RDD基本转换

二、spark streaming从某一时间戳消费

粗粒度的方式(误差约±15分钟)
在这里插入图片描述
记得改回接上次,否则重启后又回溯旧数据了

三、使用pyspark时,机器上没装 numpy

archives=viewfs:///user/hadoop-test/hdp-sample/numpy_env.zipspark.yarn.appMasterEnv.PYSPARK_PYTHON=./numpy_env.zip/numpy_env/bin/python

将以上设置加到配置里面

四、spark中创建指定格式的RDD

val rdd:RDD[(String,Int)] = sc.makeRDD(List(("k01",3),("k02",6),("k03",2),("k01",26)))
val rdd:RDD[(String,Int)] = sc.parallelize(List(("k01",3),("k02",6),("k03",2),("k01",26)))

Spark笔记:RDD基本操作(上)

Spark笔记:RDD基本操作(下)

五、写入HDFS时报错目录已经存在

可以指定覆盖写入

conf.set("spark.hadoop.validateOutputSpecs","false")

六、spark streaming 使用fastjson

在spark-steaming中,使用fast-json更加稳定,json-lib经常出现莫名问题,而且fastjson的解析速度更快.

import com.alibaba.fastjson.JSON

object Json {
  def main(args: Array[String]): Unit = {
    val str2 = "{\"et\":\"kanqiu_client_join\",\"vtm\":1435898329434,\"body\":{\"client\":\"866963024862254\",\"client_type\":\"android\",\"room\":\"NBA_HOME\",\"gid\":\"\",\"type\":\"\",\"roomid\":\"\"},\"time\":1435898329}"
       val json=JSON.parseObject(str2)
       //获取成员
       val fet=json.get("et")
       //返回字符串成员
       val etString=json.getString("et")
       //返回整形成员
       val vtm=json.getInteger("vtm")
       println(vtm)
       //返回多级成员
       val client=json.getJSONObject("body").get("client")
       println(client)

https://blog.csdn.net/qq_36330643/article/details/77152430

七、spark中创建空的RDD

val emptyRDD = new SparkContext(new SparkConf()).emptyRDD[T]

https://blog.csdn.net/chen20111/article/details/80943849

八、HDFS上传文件

hadoop fs -mkdir  ./test/
hadoop  fs -put testv3  ./test/

注意上面的 /

九、spark中filter操作使用全局变量提示没有初始化问题

该操作默认使用了全局变量,期间如果改动该变量值,会造成无法使用最新的数值;

最佳方案:filter操作等里面使用传入值的变量,比较稳定

十、Caused by: org.apache.spark.SparkException: A master URL must be set in your

在spark运行日志中(运行模式是yarn)会有三个yarn.client出现,说明每个子类任务都会有一个相对应的driver,这个说明每个子类的任务开始都会实例化自身的sparkSession,但是一个spark 应用对应了一个main函数,放在一个driver里,driver里有一个对应的实例(spark context).driver 负责向各个节点分发资源以及数据。那么如果你把创建实例放在了main函数的外面,driver就没法分发了。所以如果这样写在local模式下是可以成功的,在分布式就会报错

改变代码结构把抽象类中的公有的资源,在main函数中创建

https://blog.csdn.net/sinat_33761963/article/details/51723175
https://www.cnblogs.com/ldsggv/p/9258865.html

十一、spark中[Ljava.lang.String;@7700b3c2

在spark上面跑下面代码时,即读取hdfs上面保存的list类型string,直接collect.toString后是一个string[], 所以直接打印的话是一个数组地址

读取的文本是按照换行符转换的,所以应该mkString将一个Array[String] 转换成一个stringk
val modelString2 = modelString.mkString("")



 val rddModelJson = sc.parallelize(List(modelJson))
    rddModelJson.repartition(1).saveAsTextFile(modelPath)
    println(s"保存完毕")
    
println(s"从hdfs上面加载txt并转换成模型")
    val modelText = sc.textFile(modelPath)
    val modelString = modelText.collect().toString
    println(s"读取到的模型字符串:${modelString}")

https://my.oschina.net/nenusoul/blog/662410?p=1

https://www.imooc.com/qadetail/173418

十二、Spark中将对象序列化存储到hdfs

该代码保存的为object形式

import org.apache.spark.storage.StorageLevel
import scala.collection.JavaConverters._
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.net.URI
import java.util.Date
import org.ansj.library.UserDefineLibrary
import org.ansj.splitWord.analysis.NlpAnalysis
import org.ansj.splitWord.analysis.ToAnalysis
import org.apache.hadoop.fs.FSDataInputStream
import org.apache.hadoop.fs.FSDataOutputStream
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.FileUtil
import org.apache.hadoop.fs.Path
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor, TableName}
import org.apache.hadoop.hbase.filter.FilterList
import org.apache.hadoop.hbase.filter.PageFilter
import org.apache.hadoop.hbase.filter.RegexStringComparator
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.protobuf.ProtobufUtil
import org.apache.hadoop.hbase.util.{Base64, Bytes}
import com.feheadline.fespark.db.Neo4jManager
import com.feheadline.fespark.util.Env
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.rdd._
import org.apache.spark.mllib.feature.{Word2Vec, Word2VecModel}
import scala.math.log
import scala.io.Source

object Word2VecDemo {

  def convertScanToString(scan: Scan) = {
    val proto = ProtobufUtil.toScan(scan)
    Base64.encodeBytes(proto.toByteArray)
  }

  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setAppName("Word2Vec Demo")
    sparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    sparkConf.set("spark.kryoserializer.buffer", "256m")
    sparkConf.set("spark.kryoserializer.buffer.max","2046m")
    sparkConf.set("spark.akka.frameSize", "500")
    sparkConf.set("spark.rpc.askTimeout", "30")
    

    val sc = new SparkContext(sparkConf)
    val hbaseConf = HBaseConfiguration.create()
    hbaseConf.set("hbase.zookeeper.quorum", "myzookeeper")

    hbaseConf.set(TableInputFormat.INPUT_TABLE, "crawled")

    val scan = new Scan()
    val filterList:FilterList = new FilterList(FilterList.Operator.MUST_PASS_ALL)
    
    val comp:RegexStringComparator = new RegexStringComparator(""".{1500,}""")
    
    val articleFilter:SingleColumnValueFilter = new SingleColumnValueFilter(
    "data".getBytes,
    "article".getBytes,
    CompareOp.EQUAL,
    comp
    )
    
    filterList.addFilter(articleFilter)
    filterList.addFilter(new PageFilter(100))
    
    scan.setFilter(filterList)
    scan.setCaching(50)
    scan.setCacheBlocks(false)
    hbaseConf.set(TableInputFormat.SCAN,convertScanToString(scan))

    val crawledRDD = sc.newAPIHadoopRDD(
      hbaseConf,
      classOf[TableInputFormat],
      classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
      classOf[org.apache.hadoop.hbase.client.Result]
    )
 
    val articlesRDD = crawledRDD.filter{
      case (_,result) => {
          val content = Bytes.toString(result.getValue("data".getBytes,"article".getBytes))
          content != null
      }
    }

    val wordsInDoc = articlesRDD.map{
      case (_,result) => {
          val content = Bytes.toString(result.getValue("data".getBytes,"article".getBytes))
          if(content!=null)ToAnalysis.parse(content).asScala.map(_.getName).toSeq
          else Seq("")
      }
    }
    
    val fitleredWordsInDoc = wordsInDoc.filter(_.nonEmpty)
    
    val word2vec = new Word2Vec()
    val model = word2vec.fit(fitleredWordsInDoc)
   
    //---------------------------------------重点看这里-------------------------------------------------------------
    //将上面的模型存储到hdfs
    val hadoopConf = sc.hadoopConfiguration
    hadoopConf.set("fs.defaultFS", "hdfs://myhadoop:9000/")
    val fileSystem = FileSystem.get(hadoopConf)
    val path = new Path("/user/hadoop/data/mllib/word2vec-object")
    val oos = new ObjectOutputStream(new FSDataOutputStream(fileSystem.create(path)))
    oos.writeObject(model)
    oos.close
    
    //这里示例另外一个程序直接从hdfs读取序列化对象使用模型
    val ois = new ObjectInputStream(new FSDataInputStream(fileSystem.open(path)))
    val sample_model = ois.readObject.asInstanceOf[Word2VecModel]
   
    /*
    * //你还可以将序列化文件从hdfs放到本地, scala程序使用模型
    * import java.io._
    * import org.apache.spark.mllib.feature.{Word2Vec, Word2VecModel}
    * val ois = new ObjectInputStream(new FileInputStream("/home/cherokee/tmp/word2vec-object"))
    * val sample_model = ois.readObject.asInstanceOf[Word2VecModel]
    * ois.close
    */
    //--------------------------------------------------------------------------------------------------------------
  }
}

https://my.oschina.net/waterbear/blog/525347

十三、hdfsTotal size of serialized results of 16 tasks (1048.5 MB) is bigger than spark.driver.maxResultSize (1024.0 MB)

当操作data.take(5).foreach(println)时发生上述报错

conf.set("spark.driver.maxResultSize", "4g")

https://stackoverflow.com/questions/47996396/total-size-of-serialized-results-of-16-tasks-1048-5-mb-is-bigger-than-spark-dr

十四、spark海量数据去重策

采用分区排序去重

DataFrame.drop_duplicates(subset=None, keep=‘first’, inplace=False)

https://blog.csdn.net/MsSpark/article/details/83451491
https://blog.csdn.net/abc50319/article/details/80353808

十五、spark解决group by造成的数据倾斜问题

主要是将倾斜的数据加上随机前缀,二次处理,逐渐降低处理压力

https://blog.csdn.net/iilegend/article/details/97676109
https://blog.csdn.net/qq_38799155/article/details/80178022

十六、spark2.2与spark1.6变动部分

spark2.2使用了dataSet的封装格式,因此1.6版本中的从DataFrame提取到的rdd在2.2中会变成dataSet,需要使用 .rdd 操作进行转换,前提是没有使用各种高级api,建议自己写各种方法

https://blog.csdn.net/iilegend/article/details/97676109
https://blog.csdn.net/qq_38799155/article/details/80178022

十七、spark2.2报错java.io.InvalidClassException: org.apache.spark.sql.catalyst.expressions.GenericRow; local class incompatible: stream classdesc serialVersionUID = -1935478142066148712, local class serialVersionUID = -17966769693457883

注意下面的.cache和.rdd顺序

 dataRdd.write.parquet(path)
val dataAll = sqlContext.read.parquet(allDataFiles).na.drop().cache().rdd

val dataAll = sqlContext.read.parquet(allDataFiles).na.drop().rdd.cache()   
//该写法会报上面的错!!

内部函数传参时,尤其使用mapValues时,不要传参SparkContext上,该类没有序列化

https://blog.csdn.net/u010770919/article/details/41441149

十八、spark2.2报错 InvalidClassException: no valid constructor或者Caused by: java.io.NotSerializableException: org.apache.mahout.math.DenseMatrix

在使用序列化和反序列化时,如果使用的类没有空的构造函数,就会报这个错误;需要注意的是父类如果既没有继承序列化也没有空的构造函数,则子类此时无法写空的构造函数;解决方法是提取父类方法到子类中,子类直接继承序列化接口;

十九、spark2.2如何对rdd median 中位数求解

通过带索引的rdd进行lookup操作

import org.apache.spark.SparkContext._

  val rdd: RDD[Int] = ???

  val sorted = rdd.sortBy(identity).zipWithIndex().map {
    case (v, idx) => (idx, v)
  }

  val count = sorted.count()

  val median: Double = if (count % 2 == 0) {
    val l = count / 2 - 1
    val r = l + 1
    (sorted.lookup(l).head + sorted.lookup(r).head).toDouble / 2
  } else sorted.lookup(count / 2).head.toDouble

https://www.cnblogs.com/bonelee/p/7154234.html

二十、spark2.2中的DataSet和SparkSession

1.主要接口变化
1.1 SparkSession
Spark2.0向前兼容了之前的SparkContext以及HiveContext,同时新增了一个统一的入口:SparkSession,可以简单的认为SparkSession集成了SparkContext和HiveContext。

使用enableHiveSupport就能够支持hive,相当于hiveContext,如:

// 创建一个支持Hive的SparkSession
val sparkSession = SparkSession.builder().enableHiveSupport().getOrCreate()
 
// sql查询
sparkSession.sql("select * from xxx limit 10")

2.2 RDD/DataFrame/Dataset
区别和联系:

RDD:类型安全,面向对象编程风格,接口灵活

DataFrame:提供了查询优化器,分区剪枝,自动判断是否使用broadcast join等功能,对rdd进行了大量的优化。对spark了解不深的编程/分析人员非常友好。可以视为Row类型的Dataset (Dataset[Row]),非类型安全。

DataSet:继承了DataFrame的优点,强类型安全,面向对象编程风格。

在官方的描述中RDD以后将会逐步作为spark内部的底层接口,鼓励开发者尽量使用DataSet接口编程。

DataSet创建:Dataset 结合了 rdd 和 DataFrame 上大多数的API,可以从rdd,dataFrame转化,也可以从原始数据直接生成。

//创建RDD
scala> val rdd1 = sc.textFile("README.md")
rdd1: org.apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[3] at textFile at <console>:24

//创建DataFrame
scala> val df = spark.read.text("README.md")
df: org.apache.spark.sql.DataFrame = [value: string]

//创建DataSet
scala> val ds1 = spark.read.textFile("README.md")
ds1: org.apache.spark.sql.Dataset[String] = [value: string]

//RDD转换为DataSet
scala> val ds2 = rdd1.toDF().as[String]
ds2: org.apache.spark.sql.Dataset[String] = [value: string]

//DataFrame转换为DataSet
scala> val ds3 = df.as[String]
ds3: org.apache.spark.sql.Dataset[String] = [value: string] 

二十一、Spark Session用法DataSet与DataFrame转换成RDD

https://www.cnblogs.com/leboop/p/9455437.html

dataFrame的用法

二十二、requirement failed: Column features must be of type org.apache.spark.ml.linalg.VectorUDT@3bfc3ba7

问题解决:

导入jar包出错:
如果您的Spark> 2.x导入
org.apache.spark.ml.linalg.Vector
并不是
org.apache.spark.mllib.linalg.Vector
https://blog.csdn.net/qq_33286695/article/details/86573446

二十三、spark中DenseMatrix和array的转换

注意下面的:val dm = DenseMatrix(e.toArray:_*)

import scala.collection.mutable.ArrayBuffer

val rows: Array[Row] = df2.collect()
//rows: Array[org.apache.spark.sql.Row] = Array([-1.35980713367,...

var e = ArrayBuffer[Array[Double]]()

for(row <- rows){
  val x = row.toSeq.toArray
  val y = x.map(_.toString.toDouble)
  e += y
}
val dm = DenseMatrix(e.toArray:_*)

https://stackoverflow.com/questions/48277673/convert-an-arrayorg-apache-spark-sql-row-to-a-densematrixdouble-in-scala

二十四、java.lang.NoSuchMethodError: com.google.common.base.Splitter.splitToList(Ljava/lang/CharSequence;)Ljava/util/List;

原因是本地的jar包被SPARK_HOME/lib中的jar覆盖。spark程序在提交到yarn时,除了上传用户程序的jar,还会上传SPARK_HOME的lib目录下的所有jar包(参考附录2 )。如果你程序用到的jar与SPARK_HOME/lib下的jar发生冲突,那么默认会优先加载SPARK_HOME/lib下的jar,而不是你程序的jar,所以会发生“ NoSuchMethodError”。

程序的jar用的是guava18版本(mvn dependency:tree可查出版本),但是SPARK_HOME/lib下用的是guava14版本。lib下的guava14覆盖了用户的guava18,而guava14中并没有splitToList()方法, 所以报错

由于默认情况下,优先级SPARK_HOME/lib/jar包 > 用户程序中的jar包, 如果想让用户程序jar优先执行,那么要使用 spark.yarn.user.classpath.first (spark1.3以前)或者 spark.executor.userClassPathFirst 和spark.driver.userClassPathFirst 参数。
这些参数能让用户的jar覆盖SPARK_HOME/lib的jar。在spark conf中将他们设置为"true"即可。

    val conf = new SparkConf().setAppName("test")
        conf.set("spark.driver.userClassPathFirst", "true")

https://www.jianshu.com/p/0fe48bc43a8c

二十五、Spark 键值对RDD操作

最实用的是mapValues
https://www.cnblogs.com/yongjian/p/6425772.html

二十六、java.lang.NoClassDefFoundError: Could not initialize class org.nd4j.linalg.factory.Nd4j

deeplearning4j包需要使用ND4J的本地实现作为CPU后端:采用如下带platform的依赖项

 <dependency>
            <groupId>org.nd4j</groupId>
            <artifactId>nd4j-native-platform</artifactId>
            <version>1.0.0-beta6</version>
        </dependency>

https://blog.csdn.net/bewithme/article/details/83449116
http://www.voidcn.com/article/p-ewkarike-brx.html
https://deeplearning4j.org/cn/quickstart

二十七、使用spark mllib进行随机森林和GBDT模型训练

  1. https://blog.csdn.net/weixin_34277853/article/details/93726894
  2. https://blog.csdn.net/redhatforyou/article/details/75912262?utm_source=blogxgwz1
  3. https://blog.csdn.net/oppo62258801/article/details/79279429
  4. https://www.csdn.net/gather_20/MtTaYg4sODQwNS1ibG9n.html
  5. https://baijiahao.baidu.com/s?id=1629307366316201484&wfr=spider&for=pc GBDT

二十八、Job aborted due to stage failure ExecutorLostFailure (executor 2101 exited caused by one of the running tasks) Reason: Container marked as failed: container_1491814332016_46280_01_009179 on host

  1. 移除RDD缓存操作,增加该JOB的spark.storage.memoryFraction系数值,增加该job的spark.yarn.executor.memoryOverhead值
  2. 增大分区数,使用 set spark.sql.shuffle.partitions=1000(或更大)
  3. 调整代码,减少数据读取量

https://www.cnblogs.com/cstzhou/p/6437270.html
https://blog.csdn.net/xwc35047/article/details/53933265

二十九、spark cartesian优化与加速

cartesian操作非常耗时,可以通过将其中一个broadcast,另外一个与之进行flatmap操作,即产生了笛卡尔积的交集数据

https://www.dazhuanlan.com/2019/11/17/5dd0448cc8794/?cf_chl_jschl_tk=c0f38fa619a279dc1b4624cdac9b3cf4f35c46fd-1589967586-0-Ad7WuC8GKTaQFfVIsyZ7dzpDVJARVGbVCKzn8WtIBn8ef2TZnqO2s9u1WY8O7HzsIFip2EE6HcGzgGhppsA3nN9ts5GpGVggOcwWpF46SXKv16ML4Eb2tjHBw4d87NkaXnZnPduYXZqrho70u4UA1UyfKA89V1sHVkYUPnCyHq61_D-nUET-2RgbRr0eVwtAKBBmgxyplCTKdrIKEYkw-YK3tALiBWyLKyAzw9UAsmeXGeSqn-mfJkaD9hVTrwHKXt65CncJigmcHX98J8Mk7EUPRrJFEnL7zECoYQ89Hd6Mpzu8gai7Eear2qSapy9LBw

三十、spark进行倒排索引

其实就是先进行key, value倒置,再进行reduceByKey操作
https://blog.csdn.net/u013560925/article/details/80329288

三十一、sparkHive报错java.lang.StackOverflowError

该错一般发生在解析长的字符串时,尤其是正则匹配时,可以通过调整jvm参数扩大存储

driver端的JVM参数通过spark.driver.extraJavaOptions传递

executor端的JVM参数通过spark.executor.extraJavaOptions传递

例如:

set spark.driver.extraJavaOptions=’ -XX:MaxPermSize=256m -XX:+PrintGCApplicationStoppedTime ';

set spark.driver.extraJavaOptions=-Xss50M;

set spark.executor.extraJavaOptions=-Xss50M;

java.lang.StackOverflowError:此异常说明栈内存溢出。可以设置-XX:ThreadStackSize=2048k尝试解决该问题。

https://blog.csdn.net/longyangaaoo/article/details/82252986
https://blog.csdn.net/dai451954706/article/details/73609106
https://blog.csdn.net/dai451954706/article/details/73609106?utm_source=blogxgwz4
https://blog.csdn.net/u010936936/article/details/88363449

三十二、DataFrame用法

jdbcDF .where("id = 1 or c1 = 'b'" ).show()
jdbcDF .filter("id = 1 or c1 = 'b'" ).show()
jdbcDF.unionALL(jdbcDF.limit(1))

https://blog.csdn.net/dabokele/article/details/52802150

三十三、Error with RDD[Vector];Vector takes type paramet

import org.apache.spark.ml.linalg.Vector

//不要用下面的
import org.apache.spark.mllib.linalg.{Vector, Vectors}

三十四、java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE

其实就是数据量太大,超过了分区2GB内存大小限制,spark默认的each partition size is <= 2GB

这是 spark 的一个经典错误,很有可能就是 shuffle 的时候有太大的 key 或 value 造成的(当然,此 crash 也有可能涉及 序列化、反序列化、cache 等环节原因)

建议如果有key则解决数据倾斜,如果单纯数据量大,则在执行action操作前(包括cache),一定要repartition(1000),尽量大点很正常
https://www.pianshen.com/article/3554790946/

三十五、pipeline中获取rf随机森林的特征重要度

val pipeline = new Pipeline()
  .setStages(Array(labelIndexer, featureIndexer, rf, labelConverter))
val rfModel = model.stages(2).asInstanceOf[RandomForestClassificationModel]
println("Learned classification forest model:\n" + rfModel.toDebugString)

val featureImportances = model.stages(2).asInstanceOf[RandomForestClassificationModel].featureImportances

https://spark.apache.org/docs/1.5.2/ml-ensembles.html

三十六、DateFrame列类型转换和foldLeft使用

import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.functions.col
val df: DataFrame = ...
val columns: Array[String] = df.columns
val df2: DataFrame = columns.foldLeft(df){
    (currentDF, column) => currentDF.withColumn(column, col(column).cast("string"))
}
  • 变量columns代表df这DataFrame中的所有列,是一个String类型的数组。
  • foldLeft函数的作用就是,以df为初始值,从左向右遍历columns数组,并把df和columns中的每个元素作为参数传入foldLeft后面的函数中(也就是foldLeft后面的大括号中)。
  • withColumn中将每一列转换成String类型,并覆盖currentDF中同名字段的列。因为在withColumn函数中,如果存在同名的列,默认是进行替换的。

https://blog.csdn.net/beautiful_huang/article/details/103904377

三十七、Dataframe中替换空值和Sparkexception: Values to assemble cannot be null

遇到的报错问题如下,是在使用assemble方法汇总几列时,并进行预测时报错,原因提示的比较明显,就是数据集中出现了空值
注意:这里提到的空值不仅仅是nan/null,还会包含"NULL",原因是数据源多次转换时可能会将NULL变成"NULL",比如excel2csv。。。

val featuresCol = Array("列1","列2")
val data1 = data.na.fill("0.0",featuresCol)
      .na.replace(featuresCol, Map("NULL" -> "0.0"))

在使用Spark ml时, VectorAssembler使用null异常
Sparkexception: Values to assemble cannot be null
Spark-SQL之DataFrame操作大全
Spark Dataset DataFrame空值null,NaN判断和处理

三十八、spark中使用One-Hot Encoding

//进行类别特征的的one-hot
    val indexer = new StringIndexer().setInputCol("billing_unit").setOutputCol("billing_unitIndex")
    val indexed = indexer.fit(allDataFrame).transform(allDataFrame)
    val encoder = new OneHotEncoder().setInputCol("billing_unitIndex").setOutputCol("billing_unitVec")
      // 设置最后一个是否包含
      .setDropLast(false)
    //transform 转换成稀疏向量
    val encoded = encoder.transform(indexed)
    encoded.select("billing_unit","billing_unitIndex", "billing_unitVec").show(10, truncate = false)

Spark ML 特征工程之 One-Hot Encoding
Spark MLlib特征处理:OneHotEncoder OneHot编码 —原理及实战

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值