如何在 spark 中划分数据时从 1 列创建两列?

How to make two columns from 1 column while dividing data between them in spark?

val rdd= sc.parallelize(List(41,42,43,44,45,46,47,48,49,50))

val df = rdd.toDF("numbers")

val now = what.select(when($"numbers" % 2===0,$"numbers").otherwise("").as("Even"),
                      when($"numbers"%2===1,$"numbers").otherwise("").as("Odd"))
                      .orderBy("Even","Odd").show
+----+---+
|Even|Odd|
+----+---+
|    | 41|
|    | 43|
|    | 45|
|    | 47|
|    | 49|
|  42|   |
|  44|   |
|  46|   |
|  48|   |
|  50|   |
+----+---+

我想删除偶数列和奇数列中的空值,我该怎么做?
预期输出:

+----+---+
|Even|Odd|
+----+---+
|  42| 41|
|  44| 43|
|  46| 45|
|  48| 47|
|  50| 49|
+----+---+

有很多方法可以做到这一点,这里是一个为每个偶数获取前一个奇数的方法:

import org.apache.spark.sql.expressions.Window

val df2 = df.select(
    $"numbers".alias("even"),
    lag(when($"numbers" % 2 === lit(1), $"numbers"), 1).over(Window.orderBy("numbers")).alias("odd")
).filter("even % 2 == 0")

df2.show
+----+---+
|even|odd|
+----+---+
|  42| 41|
|  44| 43|
|  46| 45|
|  48| 47|
|  50| 49|
+----+---+

不确定您的用例是什么,但您可以创建单独的偶数和奇数数据帧,使用 RDD API 将它们压缩在一起,然后将结果转换回数据帧。它很笨重,但这并不是 Spark 驾驶室中真正存在的问题。

import org.apache.spark.sql.Row

val df = List(41,42,43,44,45,46,47,48,49,50).toDF("numbers")

val evenRDD = df.where('numbers % 2 === 0).rdd
val oddRDD = df.where('numbers % 2 === 1).rdd

val df2 = evenRDD.zip(oddRDD).map{
    case (x : Row, y : Row) => (x.getInt(0), y.getInt(0))
    }.toDF("even", "odd")

df2.show
+----+---+
|even|odd|
+----+---+
|  42| 41|
|  44| 43|
|  46| 45|
|  48| 47|
|  50| 49|
+----+---+

zip 仅当初始数据框中的奇数和偶数数量相等时才有效。如果不是,则必须通过修剪较大的多余部分或用零或其他一些无效指示符填充较小的来使它们相等。