我正在尝试编写一个PySpark脚本,该脚本将按客户所属的每个零售商的收入对客户进行排名。我当前的解决方案如下:
unique_retailers = RETAILERS.select('ID').distinct().rdd.map(lambda r: r[0]).collect()
CUSTOMERS = CUSTOMERS.orderBy(sf.col('REVENUE'), ascending=False)
for i in unique_retailers:
RANK = CUSTOMERS.select('ID').where(sf.substring(sf.col('ID'), 0, 1) == sf.lit(i)).withColumn('RANK_'+i, sf.monotonically_increasing_id())
RANK.show()
CUSTOMERS = CUSTOMERS.join(RANK, ['ID'], 'left')
CUSTOMERS.show()
在每个CUSTOMERS.ID
中,第一个字符是特定零售商的RETAILERS.ID
。但是monotonically_increasing_id())
的表现却非常出乎意料,我希望值遵循v(k+1) = v(k) + 1
的模式,但由于某些原因,它们似乎大相径庭。示例如下:
+--------+--------------------+
|ID |RANK_1 |
+--------+--------------------+
|1_502765| 0|
|1_522762| 1|
|1_532768| 17179869184|
|1_452763| 68719476736|
|1_522766| 94489280512|
|1_512769| 214748364800|
|1_542766| 223338299392|
|1_452766| 549755813888|
|1_542769| 549755813889|
|1_512766| 721554505728|
|1_132760| 962072674304|
|1_522761| 996432412672|
|1_542764| 1065151889408|
|1_172765| 1151051235328|
|1_542762| 1194000908288|
|1_542765| 1245540515840|
|1_532766| 1254130450432|
|1_542760| 1400159338496|
|1_172767| 1408749273088|
|1_412764| 1511828488192|
+--------+--------------------+
答案 0 :(得分:3)
单调并不意味着连续。您实际遇到的是预期的行为。看一下documentation ...并记住,火花是分布的,因此生成连续索引(尽管并非不可能)并非易事。
scala def monotonically_increasing_id(): Column
生成单调递增的64位的列表达式 整数。
保证生成的ID单调递增,并且 唯一,但不连续。目前的实施方式 高31位的分区ID,以及每个分区内的记录号 在低33位中进行分区。假设是数据帧 分区少于10亿,每个分区少于8 十亿条记录。
作为示例,考虑一个具有两个分区的DataFrame,每个分区有3个 记录。该表达式将返回以下ID:
0, 1, 2, 8589934592 (1L << 33), 8589934593, 8589934594.