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的值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |