添加一列,包括数据帧中从1到n的值

时间:2017-03-09 08:44:41

标签: pyspark

我正在使用pyspark创建一个数据框,如下所示:

+----+------+
|   k|     v|
+----+------+
|key1|value1|
|key1|value1|
|key1|value1|
|key2|value1|
|key2|value1|
|key2|value1|
+----+------+

我想使用'withColumn'方法添加一个'rowNum'列,dataframe的结果改变如下:

+----+------+------+
|   k|     v|rowNum|
+----+------+------+
|key1|value1|     1|
|key1|value1|     2|
|key1|value1|     3|
|key2|value1|     4|
|key2|value1|     5|
|key2|value1|     6|
+----+------+------+

rowNum的范围是从1到n,n等于raw的数量。我修改了我的代码,如下:

from pyspark.sql.window import Window
from pyspark.sql import functions as F
w = Window().partitionBy("v").orderBy('k')
my_df= my_df.withColumn("rowNum", F.rowNumber().over(w))

但是,我收到了错误消息:

'module' object has no attribute 'rowNumber' 

我用row_number替换了rowNumber()方法,上面的代码可以运行。但是,当我运行代码时:

my_df.show()

我再次收到错误消息:

Py4JJavaError: An error occurred while calling o898.showString.
: java.lang.UnsupportedOperationException: Cannot evaluate expression: row_number()
    at org.apache.spark.sql.catalyst.expressions.Unevaluable$class.doGenCode(Expression.scala:224)
    at org.apache.spark.sql.catalyst.expressions.aggregate.DeclarativeAggregate.doGenCode(interfaces.scala:342)
    at org.apache.spark.sql.catalyst.expressions.Expression$$anonfun$genCode$2.apply(Expression.scala:104)
    at org.apache.spark.sql.catalyst.expressions.Expression$$anonfun$genCode$2.apply(Expression.scala:101)
    at scala.Option.getOrElse(Option.scala:121)

4 个答案:

答案 0 :(得分:1)

如果您需要从1到n的连续rowNum值,而不是monotonically_increasing_id,则可以使用zipWithIndex()

按如下方式重新创建示例数据:

rdd = sc.parallelize([('key1','value1'),
                      ('key1','value1'),
                      ('key1','value1'),
                      ('key1','value1'),
                      ('key1','value1'),
                      ('key1','value1')])

然后,您可以使用zipWithIndex()为每行添加索引。 map用于重新格式化数据并将1添加到索引,因此它从1开始。

rdd_indexed = rdd.zipWithIndex().map(lambda x: (x[0][0],x[0][1],x[1]+1))
df = rdd_indexed.toDF(['id','score','rowNum'])
df.show()


+----+------+------+
|  id| score|rowNum|
+----+------+------+
|key1|value1|     1|
|key1|value1|     2|
|key1|value1|     3|
|key1|value1|     4|
|key1|value1|     5|
|key1|value1|     6|
+----+------+------+

答案 1 :(得分:1)

您可以使用from pyspark.sql.window import Window from pyspark.sql.functions import rowNumber w = Window().orderBy() your_df= your_df.withColumn("rowNum", rowNumber().over(w))

执行此操作
tr

此处 your_df 是您需要此列的数据框。

答案 2 :(得分:1)

我使用过spark2.2,发现“ row_number()”有效。

import pyspark.sql import functions as F
import pyspark.sql.window import Window

win_row_number = Window.orderBy("col_name")
df_row_number = df.select("col_name", F.row_number().over(win_row_number))

答案 3 :(得分:1)

Spark 2.2中的解决方案:

from pyspark.sql.functions import row_number,lit
from pyspark.sql.window import Window
w = Window().orderBy(lit('A'))
df = df.withColumn("rowNum", row_number().over(w))