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|
+----+---+
@CharlieFlowers Я добавил чек
Не уверен, какой у вас вариант использования, но вы можете создать отдельные кадры данных четных и нечетных значений, объединить их вместе с помощью 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
будет работать только в том случае, если у вас есть равное количество нечетных и четных значений в исходном фрейме данных. Если нет, вам придется сделать их равными, либо обрезав лишнее в большем, либо дополнив меньшее нулями или каким-либо другим индикатором недействительности.
Но это будет захватывать только значение, предшествующее четному числу, без проверки, нечетное оно или нет. Это будет работать для приведенного примера, но не является общим решением.