我通过执行以下命令创建了两个数据帧。
test1 = sc.parallelize([
("a",1,1),
("b",2,2),
("d",4,2),
("e",4,1),
("c",3,4)]).toDF(['SID','SSection','SRank'])
test1.show()
+---+--------+-----+
|SID|SSection|SRank|
+---+--------+-----+
| a| 1| 1|
| b| 2| 2|
| d| 4| 2|
| e| 4| 1|
| c| 3| 4|
+---+--------+-----+
test2=sc.parallelize([
("a",1,1),
("b",2,3),
("f",4,2),
("e",4,1),
("c",3,4)]).toDF(['SID','SSection','SRank'])
test2.show()
+---+--------+-----+
|SID|SSection|SRank|
+---+--------+-----+
| a| 1| 1|
| b| 2| 3|
| f| 4| 2|
| e| 4| 1|
| c| 3| 4|
+---+--------+-----+
使用test1和test2数据帧我需要生成新的数据帧,其中应包含如下所示的结果。
+---+--------+----------+------------+------------+
|SID|SSection|test1SRank|test2SRank | flag |
+---+--------+----------+------------+------------+
| a| 1| 1 | 1 | same_rank |
| b| 2| 2 | 3 |rank_changed|
| d| 4| 2 | 0 |No_rank |
| e| 4| 1 | 1 |same_rank |
| c| 3| 4 | 4 |same_rank |
| f| 4| 0 | 2 |new_rank |
+---+--------+----------+------------+------------+
以上结果我想通过使用SID
和SSection
列的组合以及ranks
之间的比较来比较test1和test2数据框。
例如:
1)SID (a)
和SSection (1)
:test1rank为1
,test2rank为1
,因此我的旗帜值应为same_rank
。
2)SID (b)
和SSection (2)
:test1rank为2
,test2rank为3
此处的排名已更改,因此我的标记值应为rank_changed
3)SID (d)
和SSection (4)
:在test1rank中为2
,在test2rank中他失去了排名,因此我的旗帜值应为No_rank
4)SID (f)
和SSection (4)
:在test1rank中他没有表现好,所以他没有任何等级,在test2rank他表现不错,他的等级是2,所以我的旗帜值应该是{ {1}}
答案 0 :(得分:1)
这可以给你你想要的东西:
from pyspark.sql import functions as f
test3=test1.withColumnRenamed('SRank','test1SRank')\
.join(test2.drop('SSection')\
.withColumnRenamed('SRank','test2SRank'), on='SID', how='outer')\
.fillna(0)
test3=test3.withColumn('flag', f.expr("case when test1SRank=0 and test2SRank>0 then 'new_rank'\
when test1SRank>0 and test2SRank=0 then 'No_rank'\
when test1SRank=test2SRank then 'same_rank'\
else 'rank_changed' end"))
test3.orderBy('SID').show()
说明:外部加入数据框,因此您拥有所有SID的test1和test2分数。然后用0填充空值,并在语句时使用sql case执行标志逻辑。