我有一个带有一个架构的数据框。现有数据框已经有50列。现在我想在现有数据框中添加一个新列。新列名是" hashing_id"并且此hashing_id的逻辑是sha1(行)。我怎么做到这一点?
我尝试了以下代码。以下两种方法都在主类中使用的特征内。这个特性也扩展了Serializable
def addHashingKey():DataFrame={
val sha1 = java.security.MessageDigest.getInstance("SHA-1")
val enCoder = new sun.misc.BASE64Encoder()
//enCoder.encode(sha1.digest(row.mkString.getBytes))
createDataFrame(df.map(row => {
Row.fromSeq(row.toSeq ++ enCoder.encode(sha1.digest(row.mkString.getBytes)))
}), df.schema.add("hashing_id", StringType))
}
def createDataFrame(rdd: RDD[Row], schema: StructType): DataFrame = {
sqlContext.createDataFrame(rdd, schema)
}
如何使用rdd实现sha1?
有人可以帮我这个
当我运行代码时,它会抛出异常
17/09/12 13:45:20 ERROR yarn.ApplicationMaster: User class threw exception: org.apache.spark.SparkException: Task not serializable
org.apache.spark.SparkException: Task not serializable
Caused by: java.io.NotSerializableException: sun.misc.BASE64Encoder
Serialization stack:
- object not serializable (class: sun.misc.BASE64Encoder, value: sun.misc.BASE64Encoder@46c0813)
答案 0 :(得分:1)
你不能尝试这样的事情,它似乎在我的一些测试中起作用我只是运行:
val newDF = sqlContext.createDataFrame(
rdd.map(x => Row(x.toSeq ++ Seq(x.toSeq.hashCode()): _*)), StructType(schema.iterator.toSeq ++ Seq(StructField("hashing_id", StringType, true))))
显然你需要将hashCode替换为你需要的哈希函数
编辑:使用sha1功能
在另一个类中定义你的函数
object Encoder {
def sha1(s: Row): String = MessageDigest.getInstance("SHA-1").digest(s.mkString.getBytes()).toString
}
然后在原始课程中,您可以按如下方式调用您的函数
val newDF = sqlContext.createDataFrame(wordsRDD.map(x => Row(x.toSeq ++ Seq(Encoder.sha1(x)): _*)), StructType(schema.iterator.toSeq ++ Seq(StructField("hashing_id", StringType, true)))).rdd.collect()