我有一個像這樣的資料框架:
我有一個像這樣的資料框架。
name field1 field2 field3
a 4 10 8
b 5 0 11
c 10 7 4
d 0 1 5
我需要找到每個欄位的前三個名字。
預期輸出:
top3-field1 top3-field2 top3-field3
c a b
b c a
a d d
因此,我嘗試對field(n)的列值進行排序,限制前3個結果,并使用withColumn方法生成新的列,像這樣:
df1 = df.orderBy(f.col("field1"/span>).desc(), "name"/span>)
.limit(3)
.withColumn("top3-field1", df["name"])
.select("top3-field1", "field1")
使用這種方法,我必須為每個欄位(n)創建不同的資料框,然后將它們連接起來以獲得上述結果。我覺得對于這個問題一定有更好的解決方案。希望有人能給我建議
。uj5u.com熱心網友回復:
你可以先把df堆積起來,然后得到降序的等級,再過濾掉小于等于3的等級,最后透視名字:
注意,我在代碼中使用了這個函式,使堆疊本身在打字時更容易一些:
from pyspark. sql import functions as F, Window as W #imports
w = W.partitionBy("col").orderBy(F.desc("value")
out = (df.selectExpr("name",stack_multiple_col(df,df.columns[1:])
.withColumn("Rnk",F.dense_rank() .over(w))
.where("Rnk<=3").groupBy("Rnk").pivot("col").agg(F.first("name") )
out.show()
--- ------ ------ ------
|Rnk|field1|field2|field3|
--- ------ ------ ------
| 1| c| a| b|
| 2| b| c| a|
3| a| d| d|
--- ------ ------ ------
如果你不愿意使用這個函式,你可以寫成:
w = W.partitionBy("col").orderBy(F.desc(" values")
out = (df.selectExpr("name",
'stack(3, "field1",field1, "field2",field2, "field3",field3) as (col,values)' )
.withColumn("Rnk",F.dense_rank() .over(w))
.where("Rnk<=3").groupBy("Rnk").pivot("col").agg(F.first("name") )
完整的代碼:
def stack_multiple_col(df,cols=df. columns,output_columns=["col","values"])。)
""在一個資料框架中堆疊多個列。
除非通過一個值的串列,否則默認采取所有的列""。
return (f""stack({len(cols)}, {', '. join(map(','.join,
(zip([f'"{i}"'/span> for i in cols] 。 cols))))})為({','. join(output_columns)})""")
w = W.partitionBy("col").orderBy(F.desc("value")
out = (df.selectExpr("name",stack_multiple_col(df,df.columns[1:])
.withColumn("Rnk",F.dense_rank() .over(w))
.where("Rnk<=3").groupBy("Rnk").pivot("col").agg(F.first("name") )
out.show()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/310734.html
標籤:
上一篇:谷歌不收錄https
