如何使用pyspark从列表中获取最后一项?

时间:2016-11-07 14:45:12

标签: apache-spark pyspark apache-spark-sql

为什么列1st_from_end包含null:

from pyspark.sql.functions import split
df = sqlContext.createDataFrame([('a b c d',)], ['s',])
df.select(   split(df.s, ' ')[0].alias('0th'),
             split(df.s, ' ')[3].alias('3rd'),
             split(df.s, ' ')[-1].alias('1st_from_end')
         ).show()

enter image description here
我认为使用[-1]是一种pythonic方式来获取列表中的最后一项。怎么在pyspark不起作用?

4 个答案:

答案 0 :(得分:6)

不幸的是,spark数据帧不支持对数组进行-1索引,但您可以编写自己的UDF或使用内置的size()函数,例如:

>>> from pyspark.sql.functions import size
>>> splitted = df.select(split(df.s, ' ').alias('arr'))
>>> splitted.select(splitted.arr[size(splitted.arr)-1]).show()
+--------------------+
|arr[(size(arr) - 1)]|
+--------------------+
|                   d|
+--------------------+

答案 1 :(得分:1)

对于 Spark 2.40 + ,请使用pyspark.sql.functions.element_at,请参见文档中的以下内容:

  

element_at(array,index)-返回给定(从1开始)索引处的数组元素。如果index <0,则从最后到第一个访问元素。如果索引超过数组的长度,则返回NULL。

from pyspark.sql.functions import element_at, split, col

df = spark.createDataFrame([('a b c d',)], ['s',])

df.withColumn('arr', split(df.s, ' ')) \
  .select( col('arr')[0].alias('0th')
         , col('arr')[3].alias('3rd')
         , element_at(col('arr'), -1).alias('1st_from_end')
     ).show()

+---+---+------------+
|0th|3rd|1st_from_end|
+---+---+------------+
|  a|  d|           d|
+---+---+------------+

答案 2 :(得分:0)

创建自己的udf看起来像这样

    def get_last_element(l):
        return l[-1]
    get_last_element_udf = F.udf(get_last_element)

    df.select(get_last_element(split(df.s, ' ')).alias('1st_from_end')

答案 3 :(得分:0)

基于jamiet的解决方案,我们可以通过删除reverse

来进一步简化
from pyspark.sql.functions import split, reverse

df = sqlContext.createDataFrame([('a b c d',)], ['s',])
df.select(   split(df.s, ' ')[0].alias('0th'),
             split(df.s, ' ')[3].alias('3rd'),
             reverse(split(df.s, ' '))[-1].alias('1st_from_end')
         ).show()