加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala / Spark数据帧:找到与max相对应的列名

发布时间:2020-12-16 09:51:51 所属栏目:安全 来源:网络整理
导读:在 Scala / Spark中,有一个数据帧: val dfIn = sqlContext.createDataFrame(Seq( ("r0",2,3),("r1",1,0),("r2",2))).toDF("id","c0","c1","c2") 我想计算一个新列maxCol,其中包含与最大值对应的列名(对于每一行).在这个例子中,输出应该是: +---+---+---+--
在 Scala / Spark中,有一个数据帧:

val dfIn = sqlContext.createDataFrame(Seq(
  ("r0",2,3),("r1",1,0),("r2",2))).toDF("id","c0","c1","c2")

我想计算一个新列maxCol,其中包含与最大值对应的列名(对于每一行).在这个例子中,输出应该是:

+---+---+---+---+------+
| id| c0| c1| c2|maxCol|
+---+---+---+---+------+
| r0|  0|  2|  3|    c2|
| r1|  1|  0|  0|    c0|
| r2|  0|  2|  2|    c1|
+---+---+---+---+------+

实际上,数据框有超过60列.因此,需要通用的解决方案.

Python Pandas中的等价物(是的,我知道,我应该与pyspark进行比较……)可能是:

dfOut = pd.concat([dfIn,dfIn.idxmax(axis=1).rename('maxCol')],axis=1)

解决方法

通过一个小技巧,您可以使用最大的功能.所需进口:

import org.apache.spark.sql.functions.{col,greatest,lit,struct}

首先让我们创建一个结构列表,其中第一个元素是值,第二个是列名:

val structs = dfIn.columns.tail.map(
  c => struct(col(c).as("v"),lit(c).as("k"))
)

像这样的结构可以传递到最大,如下所示:

dfIn.withColumn("maxCol",greatest(structs: _*).getItem("k"))
+---+---+---+---+------+
| id| c0| c1| c2|maxCol|
+---+---+---+---+------+
| r0|  0|  2|  3|    c2|
| r1|  1|  0|  0|    c0|
| r2|  0|  2|  2|    c2|
+---+---+---+---+------+

请注意,在连接的情况下,它将采用序列中稍后出现的元素(按字典顺序排列(x,“c2”)>(x,“c1”)).如果出于某种原因这是不可接受的,您可以在以下时间明确减少:

import org.apache.spark.sql.functions.when

val max_col = structs.reduce(
  (c1,c2) => when(c1.getItem("v") >= c2.getItem("v"),c1).otherwise(c2)
).getItem("k")

dfIn.withColumn("maxCol",max_col)
+---+---+---+---+------+
| id| c0| c1| c2|maxCol|
+---+---+---+---+------+
| r0|  0|  2|  3|    c2|
| r1|  1|  0|  0|    c0|
| r2|  0|  2|  2|    c1|
+---+---+---+---+------+

如果是可空列,则必须对其进行调整,例如通过合并到-Inf的值.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读