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

jam*_*iet 6 apache-spark apache-spark-sql pyspark

为什么列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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述
我认为使用[-1]是一种pythonic方式来获取列表中的最后一项.怎么会在pyspark不起作用?

jxc*_*jxc 16

对于Spark 2.4+,使用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|
+---+---+------------+
Run Code Online (Sandbox Code Playgroud)


Mar*_*usz 11

遗憾的是,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|
+--------------------+
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你证实了我的怀疑。我的解决方案比这更笨拙:`reverse(split(reverse(df.s), ' ')[0])` (2认同)