web-dev-qa-db-fra.com

Comment faire exploser les colonnes?

Après:

val df = Seq((1, Vector(2, 3, 4)), (1, Vector(2, 3, 4))).toDF("Col1", "Col2")

J'ai ce DataFrame dans Apache Spark: 

+------+---------+
| Col1 | Col2    |
+------+---------+
|  1   |[2, 3, 4]|
|  1   |[2, 3, 4]|
+------+---------+

Comment puis-je convertir cela en:

+------+------+------+------+
| Col1 | Col2 | Col3 | Col4 |
+------+------+------+------+
|  1   |  2   |  3   |  4   |
|  1   |  2   |  3   |  4   |
+------+------+------+------+
12
Jorge Machado

Une solution qui ne convertit pas vers et depuis RDD:

df.select($"Col1", $"Col2"(0) as "Col2", $"Col2"(1) as "Col3", $"Col2"(2) as "Col3")

Ou discutable plus agréable:

val nElements = 3
df.select(($"Col1" +: Range(0, nElements).map(idx => $"Col2"(idx) as "Col" + (idx + 2)):_*))

La taille d'une colonne d'un tableau Spark n'est pas fixe, vous pourriez par exemple avoir:

+----+------------+
|Col1|        Col2|
+----+------------+
|   1|   [2, 3, 4]|
|   1|[2, 3, 4, 5]|
+----+------------+

Il n’ya donc aucun moyen d’obtenir le - montant des colonnes et de les créer. Si vous savez que la taille est toujours la même, vous pouvez définir nElements comme ceci:

val nElements = df.select("Col2").first.getList(0).size
18
sgvd

Juste pour donner la version Pyspark de la réponse de sgvd . Si la colonne de tableau est dans Col2, cette instruction select déplacera la première nElements de chaque tableau dans Col2 dans leurs propres colonnes:

from pyspark.sql import functions as F            
df.select([F.col('Col2').getItem(i) for i in range(nElements)])
2
Shane Halloran

Ajoutez simplement à sgvd's solution:

Si la taille n'est pas toujours la même, vous pouvez définir nElements de la manière suivante:

val nElements = df.select(size('Col2).as("Col2_count"))
                  .select(max("Col2_count"))
                  .first.getInt(0)
1
Yuan Zhao

Vous pouvez utiliser une carte:

df.map {
    case Row(col1: Int, col2: mutable.WrappedArray[Int]) => (col1, col2(0), col2(1), col2(2))
}.toDF("Col1", "Col2", "Col3", "Col4").show()
0
Carlos Vilchez