一次在多个Spark DataFrame列上运行

时间:2017-07-11 13:27:54

标签: scala apache-spark dataframe md5 user-defined-functions

我需要一次计算多个数据帧列的md5哈希值。

功能

def md5 = udf((s: String) => toHex(MessageDigest.getInstance("MD5").digest(s.getBytes("UTF-8"))))
def toHex(bytes: Array[Byte]): String = bytes.map("%02x".format(_)).mkString("")

一栏示例

var test_df = load_df.as('a).select($"a.attr1", md5($"a.attr2").as("hash_key"))

+-------------+--------------------+
|     attr1   |            hash_key|
+-------------+--------------------+
|9/1/2015 0:23|7a2f516dad8f13ae1...|
|9/1/2015 0:31|339c72b1870c3a6be...|
|9/1/2015 0:19|7065847af7abc6bce...|
|9/1/2015 1:32|38c7276958809893b...|

使用一列(a.attr2)生成的工作非常好,但我找不到将多列插入/连接到md5()函数的好方法。

3 个答案:

答案 0 :(得分:3)

您应该使用md5(concat_ws(",",$"a.attr2",$"a.attr3",$"a.attr4")) ,如下所示:

Seq(("a","b","c")).toDF("x","y","z").withColumn("foo", md5(concat_ws(",",$"x",$"y",$"z"))).show(false)
// +---+---+---+--------------------------------+
// |x  |y  |z  |foo                             |
// +---+---+---+--------------------------------+
// |a  |b  |c  |a44c56c8177e32d3613988f4dba7962e|
// +---+---+---+--------------------------------+

以下是一个例子:

CREATE TABLE IF NOT EXISTS users  (
columns.......
)

答案 1 :(得分:1)

就个人而言,我会在UDF中进行连接,这会给你更多的灵活性:

e.g。传递字符串数组:

val md5 = udf((arrs:Seq[String]) => {
  val s = arrs.mkString(",")
  // do something with s
  s
 })    

df.withColumn("md5",md5(array($"x",$"y",$"z")))

甚至传递整行,如果您有混合类型的列,这也可以工作:

val md5 = udf((r:Row) => {
  val s = r.mkString(",")
  // do something with s
  s
 })

df.withColumn("md5",md5(struct($"x",$"y",$"z")))

答案 2 :(得分:0)

如果您想使用自定义分隔符连接所有列,请使用:

 includeheader on

用于计算行哈希。