pyspark dataframe 获得每一行的第二低值
pyspark dataframe get second lowest value for each row
我想问一下,如果有人有想法,如何在pyspark中获取Dataframe一行中第二低的值。
例如:
输入数据帧:
Col1 Col2 Col3 Col4
83 32 14 62
63 32 74 55
13 88 6 46
预期输出:
Col1 Col2 Col3 Col4 Res
83 32 14 62 32
63 32 74 55 55
13 88 6 46 13
我们可以使用 concat_ws
函数连接该行的所有列,然后使用 split
来创建一个数组。
使用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|
#+----+----+----+----+---+
您可以使用 array
function and then sort it using array_sort
. Finally, get the second element using element_at
创建数组列。这 2 个最后的功能可从 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 |
#+----+----+----+----+---+
另一种方法是使用least
函数。首先,计算所有列的最小值,然后使用 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()
我想问一下,如果有人有想法,如何在pyspark中获取Dataframe一行中第二低的值。
例如:
输入数据帧:
Col1 Col2 Col3 Col4
83 32 14 62
63 32 74 55
13 88 6 46
预期输出:
Col1 Col2 Col3 Col4 Res
83 32 14 62 32
63 32 74 55 55
13 88 6 46 13
我们可以使用 concat_ws
函数连接该行的所有列,然后使用 split
来创建一个数组。
使用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|
#+----+----+----+----+---+
您可以使用 array
function and then sort it using array_sort
. Finally, get the second element using element_at
创建数组列。这 2 个最后的功能可从 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 |
#+----+----+----+----+---+
另一种方法是使用least
函数。首先,计算所有列的最小值,然后使用 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()