如何爆列?
How to explode columns?
之后:
val df = Seq((1, Vector(2, 3, 4)), (1, Vector(2, 3, 4))).toDF("Col1", "Col2")
我在 Apache Spark 中有这个 DataFrame:
+------+---------+
| Col1 | Col2 |
+------+---------+
| 1 |[2, 3, 4]|
| 1 |[2, 3, 4]|
+------+---------+
如何将其转换为:
+------+------+------+------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------+
| 1 | 2 | 3 | 4 |
| 1 | 2 | 3 | 4 |
+------+------+------+------+
您可以使用地图:
df.map {
case Row(col1: Int, col2: mutable.WrappedArray[Int]) => (col1, col2(0), col2(1), col2(2))
}.toDF("Col1", "Col2", "Col3", "Col4").show()
不与RDD相互转换的解决方案:
df.select($"Col1", $"Col2"(0) as "Col2", $"Col2"(1) as "Col3", $"Col2"(2) as "Col3")
或有争议的更好:
val nElements = 3
df.select(($"Col1" +: Range(0, nElements).map(idx => $"Col2"(idx) as "Col" + (idx + 2)):_*))
Spark 数组列的大小不固定,例如您可以:
+----+------------+
|Col1| Col2|
+----+------------+
| 1| [2, 3, 4]|
| 1|[2, 3, 4, 5]|
+----+------------+
因此无法获得 列的数量并创建它们。如果您知道大小始终相同,则可以这样设置 nElements
:
val nElements = df.select("Col2").first.getList(0).size
只需添加到 sgvd 的 解决方案:
如果大小不总是一样,你可以这样设置nElements:
val nElements = df.select(size('Col2).as("Col2_count"))
.select(max("Col2_count"))
.first.getInt(0)
只是给的Pyspark版本。如果数组列在 Col2
中,则此 select 语句会将 Col2
中每个数组的第一个 nElements
移动到它们自己的列中:
from pyspark.sql import functions as F
df.select([F.col('Col2').getItem(i) for i in range(nElements)])
之后:
val df = Seq((1, Vector(2, 3, 4)), (1, Vector(2, 3, 4))).toDF("Col1", "Col2")
我在 Apache Spark 中有这个 DataFrame:
+------+---------+
| Col1 | Col2 |
+------+---------+
| 1 |[2, 3, 4]|
| 1 |[2, 3, 4]|
+------+---------+
如何将其转换为:
+------+------+------+------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------+
| 1 | 2 | 3 | 4 |
| 1 | 2 | 3 | 4 |
+------+------+------+------+
您可以使用地图:
df.map {
case Row(col1: Int, col2: mutable.WrappedArray[Int]) => (col1, col2(0), col2(1), col2(2))
}.toDF("Col1", "Col2", "Col3", "Col4").show()
不与RDD相互转换的解决方案:
df.select($"Col1", $"Col2"(0) as "Col2", $"Col2"(1) as "Col3", $"Col2"(2) as "Col3")
或有争议的更好:
val nElements = 3
df.select(($"Col1" +: Range(0, nElements).map(idx => $"Col2"(idx) as "Col" + (idx + 2)):_*))
Spark 数组列的大小不固定,例如您可以:
+----+------------+
|Col1| Col2|
+----+------------+
| 1| [2, 3, 4]|
| 1|[2, 3, 4, 5]|
+----+------------+
因此无法获得 列的数量并创建它们。如果您知道大小始终相同,则可以这样设置 nElements
:
val nElements = df.select("Col2").first.getList(0).size
只需添加到 sgvd 的 解决方案:
如果大小不总是一样,你可以这样设置nElements:
val nElements = df.select(size('Col2).as("Col2_count"))
.select(max("Col2_count"))
.first.getInt(0)
只是给Col2
中,则此 select 语句会将 Col2
中每个数组的第一个 nElements
移动到它们自己的列中:
from pyspark.sql import functions as F
df.select([F.col('Col2').getItem(i) for i in range(nElements)])