通过其他键将列添加到具有非唯一ID的pyspark数据框

时间:2018-10-30 13:58:45

标签: python pyspark pyspark-sql

道歉标题-不知道如何轻松总结我的问题。

我有一个带有2列的pyspark数据框,代码和emp。每个唯一的代码值都有多个emp值,如下所示。我希望添加一列,该列为每个唯一的代码值应用一个递增的数字,例如下面的值列。我玩过monotonicallyIncreasingId(),还没有设法将其ID的创建限制为一个特定的代码键,实际上,文档说索引不必按顺序递增。

+----+---+-----+
|code|emp|value|
+----+---+-----+
|   a| 14|    1|
|   a| 22|    2|
|   a| 35|    3|
|   a| 64|    4|
|   b| 12|    1|
...
+----+---+-----+

如果每个代码值对效率有影响,则最多为4个emp值。索引应随emp值的大小而增加-最低值应具有值1,最高值n,其中n是具有特定代码的记录数。

3 个答案:

答案 0 :(得分:1)

您可以将 row_number() Windowing 功能一起使用。

首先导入 Window row_number

from pyspark.sql import Window
from pyspark.sql.functions import row_number()

假设您的方案具有以下列和值

>>> cols1 = ['code', 'emp']
>>> vals1 = [
     ('a', 14),
     ('a', 22),
     ('a', 35),
     ('a', 64),
     ('b', 12),
     ('b', 35)
]
# Create a DataFrame
>>> df1 = spark.createDataFrame(vals1, cols1)

# Result of 'df1' table.
>>> df1.show()
+----+---+
|code|emp|
+----+---+
|   a| 14|
|   a| 22|
|   a| 35|
|   a| 64|
|   b| 12|
|   b| 35|
+----+---+

在第code列上应用 row_number()

>>> val = df1.withColumn("value", row_number().over(Window.partitionBy("code").orderBy("emp")))

>>> val.show()
+----+---+-----+
|code|emp|value|
+----+---+-----+
|   b| 12|    1|
|   b| 35|    2|
|   a| 14|    1|
|   a| 22|    2|
|   a| 35|    3|
|   a| 64|    4|
+----+---+-----+

最后,按列code排序以获得所需的结果。

>>> val.orderBy('code').show()
+----+---+-----+
|code|emp|value|
+----+---+-----+
|   a| 14|    1|
|   a| 22|    2|
|   a| 35|    3|
|   a| 64|    4|
|   b| 12|    1|
|   b| 35|    2|
+----+---+-----+
  • partitionBy :创建带有已定义分区的WindowSpec。

有关更多信息,请参阅:

答案 1 :(得分:0)

对于Scala,您可以使用以下增量索引列创建一个数据框:

%scala
val rankedWordCount = sqlContext.sql("select row_number() over (order by some_numeric_value desc) as index_col,lower(info) as info, some_numeric_value from information_table")

答案 2 :(得分:0)

您可以创建一个临时视图并为此使用Spark SQL:

>>> df = spark.createDataFrame([('a', 14), ('a', 22), ('a', 35), ('a', 64), ('b', 12)], ['code', 'emp'])
>>> df.show()
+----+---+
|code|emp|
+----+---+
|   a| 14|
|   a| 22|
|   a| 35|
|   a| 64|
|   b| 12|
+----+---+
>>> df.createOrReplaceTempView("df")
>>> df2 = spark.sql("select code, emp, row_number() over(partition by code order by emp) as value from df order by code")
>>> df2.show()
+----+---+-----+
|code|emp|value|
+----+---+-----+                                                                                                         
|   a| 14|    1|                                                                                                             
|   a| 22|    2|                                                                                                             
|   a| 35|    3|                                                                                                          
|   a| 64|    4| 
|   b| 12|    1|                                                                                                             
+----+---+-----+