我使用Java运行Spark 1.5。我需要将ID / Index列附加到现有的DataFrame,例如:
+---------+--------+
| surname| name|
+---------+--------+
| Green| Jake|
| Anderson| Thomas|
| Corleone| Michael|
| Marsh| Randy|
| Montana| Tony|
| Green| Julia|
|Brenneman| Eady|
| Durden| Tyler|
| Corleone| Vito|
| Madiro| Mat|
+---------+--------+
我希望每行都附加索引,范围在介于1和表记录之间之间。索引顺序无关紧要,任何行都必须只包含唯一的ID /索引。它可以通过转换为RDD并将索引行和转换附加到具有修改的StructType的DataFrame来完成,但是,如果我理解正确,此操作会消耗大量资源用于转换等,并且必须有另一种方式。 结果必须如下:
+---------+--------+---+
| surname| name| id|
+---------+--------+---+
| Green| Jake| 3|
| Anderson| Thomas| 5|
| Corleone| Michael| 2|
| Marsh| Randy| 10|
| Montana| Tony| 7|
| Green| Julia| 1|
|Brenneman| Eady| 2|
| Durden| Tyler| 9|
| Corleone| Vito| 4|
| Madiro| Mat| 6|
+---------+--------+---+
谢谢。
答案 0 :(得分:2)
我知道这个问题可能还有一段时间,但您可以按照以下方式进行:
from pyspark.sql.window import Window
w = Window.orderBy("myColumn")
withIndexDF = originalDF.withColumn("index", row_number().over(w))
答案 1 :(得分:0)
伙计们,这是一个很好的方法:
从RDD模拟ZipWithIndex方法...第一个建议表现更好,但到目前为止纯粹的Dataframes解决方案没有大问题(在我的场景中超过100M行表)。
答案 2 :(得分:0)
在Scala中,首先我们需要创建一个索引数组:
val indx_arr=(1 to your_df.count.toInt).toArray
indx_arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
现在,我们要将此列附加到Dataframe。
首先,我们打开我们的Dataframe并将其作为数组获取,然后我们使用indx_arr
将其压缩,然后将新创建的数组转换回RDD。最后一步是将其作为Dataframe:
final_df = sc.parallelize((your_df.collect.map(
x=>(x(0),x(1))) zip indx_arr).map(
x=>(x._1._1.toString,x._1._2.toString,x._2))).toDF("surname","name","id")
这也是一种简单直接的方法,可以将任何类型的数组附加到Spark Dataframe。
答案 3 :(得分:0)
在spark数据框中执行此操作的最简洁方法:
.withColumn("idx",monotonically_increasing_id())
完整文档:https://docs.databricks.com/spark/latest/sparkr/functions/withColumn.html
答案 4 :(得分:-2)
您可以使用withColumn功能。用法应该是Val myDF = existingDF.withColumn(" index",express(random(1,existingDF.count())