2017-06-06 8 views
2

DataFrameを使用するSpark-SQLバージョン1.6では、特定の列に対して、現在の行と次の行を分ける割合をすべての行について計算する方法がありますか?例えば現在の行の値を次の値に分割する方法は?

、私は

Age 
100 
50 
20 
4 

私はそれは、「次を持っていないので、最後の行がドロップされ、次の出力

Franction 
2 
2.5 
5 

したいような、一つの列を持つテーブルを持っている場合行 "に追加されます。

今私はテーブルのランキングを決めてそれ自身と結合しています。ここではrankrank+1です。

これを行うより良い方法はありますか? Window機能でこれを行うことはできますか?

+0

はい。それはウィンドウ集合関数の "仕事"です。 '/'を使いましたか? –

+0

@JacekLaskowski、 '/'または 'functions'に似たものは見つかりませんでした。 – summerbulb

答えて

2

Window関数は部分的なトリックだけを行う必要があります。他の部分的なトリックはudf機能

def div = udf((age: Double, lag: Double) => lag/age) 

ファーストを定義することによって行うことができ、我々はlagWindow機能を使用して検索し、div 輸入sqlContext.implicits._ を見つけるために、udf機能でそのlagageを渡す必要があります輸入org.apache.spark.sql.functions._

val dataframe = Seq(
    ("A",100), 
    ("A",50), 
    ("A",20), 
    ("A",4) 
).toDF("person", "Age") 

val windowSpec = Window.partitionBy("person").orderBy(col("Age").desc) 
val newDF = dataframe.withColumn("lag", lag(dataframe("Age"), 1) over(windowSpec)) 

そして最後には、UDFの機能をCAL

newDF.filter(newDF("lag").isNotNull).withColumn("div", div(newDF("Age"), newDF("lag"))).drop("Age", "lag").show 

最終的な出力は次のようになり

+------+---+ 
|person|div| 
+------+---+ 
|  A|2.0| 
|  A|2.5| 
|  A|5.0| 
+------+---+ 

@Jacekとして ではなく.filter(newDF("lag").isNotNull).na.dropを使用して/演算子を使用するために、よりよい解決策を提案しているので、私たちも、呼び出す必要はありません編集udf機能

newDF.na.drop.withColumn("div", newDF("lag")/newDF("Age")).drop("Age", "lag").show 
+2

ありがとうございます。あなたの答えを踏まえて、私は次のように構成しました。(dataframe.select($ "person"、$ "Age" /(lead) "age"、1)を "div"としました。 drop.show' – summerbulb

関連する問題