简体   繁体   English

pyspark 数据框获得每行的第二低值

[英]pyspark dataframe get second lowest value for each row

I would like to query, if anyone has an idea, how to get the second lowest value in a row of Dataframe in pyspark.我想查询,如果有人有想法,如何在 pyspark 中获得一行 Dataframe 中的第二低值。

For example:例如:

Input Dataframe :输入数据框

Col1  Col2  Col3  Col4 
83    32    14    62   
63    32    74    55   
13    88     6    46   

Expected output :预期输出

Col1  Col2  Col3  Col4 Res
83    32    14    62   32   
63    32    74    55   55   
13    88     6    46   13

We can use concat_ws function to concat all columns for the row then use split to create an array.我们可以使用concat_ws函数连接该行的所有列,然后使用split创建一个数组。

use array_sort function to sort with in the array and extract second element[1] of the array.使用array_sort函数在数组中排序并提取数组的second element[1]

Example:

from pyspark.sql.functions import *

df=spark.createDataFrame([('83','32','14','62'),('63','32','74','55'),('13','88','6','46')],['Col1','Col2','Col3','Col4'])

df.selectExpr("array_sort(split(concat_ws(',',Col1,Col2,Col3,Col4),','))[1] Res").show()

#+---+
#|Res|
#+---+
#|32 |
#|55 |
#|13 |
#+---+

More Dynamic Way:

df.selectExpr("array_sort(split(concat_ws(',',*),','))[1]").show()

#+---+
#|Res|
#+---+
#|32 |
#|55 |
#|13 |
#+---+

EDIT:

#adding Res column to the dataframe
df1=df.selectExpr("*","array_sort(split(concat_ws(',',*),','))[1] Res")
df1.show()

#+----+----+----+----+---+
#|Col1|Col2|Col3|Col4|Res|
#+----+----+----+----+---+
#|  83|  32|  14|  62| 32|
#|  63|  32|  74|  55| 55|
#|  13|  88|   6|  46| 46|
#+----+----+----+----+---+

You can create an array column using array function and then sort it using array_sort .您可以使用array函数创建一个数组列,然后使用array_sort对其进行array_sort Finally, get the second element using element_at .最后,使用element_at获取第二个元素。 These 2 last functions are available from Spark 2.4+.这最后两个函数可从 Spark 2.4+ 获得。

df.withColumn("res", element_at(array_sort(array(*[col(c) for c in df.columns])), 2))\
  .show()

#+----+----+----+----+---+
#|Col1|Col2|Col3|Col4|res|
#+----+----+----+----+---+
#|83  |32  |14  |62  |32 |
#|63  |32  |74  |55  |55 |
#|13  |88  |6   |46  |13 |
#+----+----+----+----+---+

Another way of doing is to use least function.另一种做法是使用least函数。 First, calculate the min value from all columns then calculate another time the least from values that are greater than min using when expression:首先,计算所有列的最小值,然后使用when表达式从大于min值计算另一个时间:

df.withColumn("min", least(*[col(c) for c in df.columns]))\
  .withColumn("res", least(*[when(col(c) > col("min"), col(c)) for c in df.columns]))\
  .drop("min")\
  .show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM