2017-07-06 8 views
0

をスパーク、他の列の値にデータフレームベースの列を追加する方法を、私は文字列形式で私はString型のコラム「時代」でデータフレームを持っている

範囲を範囲を含む新しい列を取得したいです

[-1、12、17、24、34、44、54、64、100 1000]例えば

入力値

Age 
===== 
-1 
12 
18 
28 
38 
46 
====== 

出力必須

を次のように
Age Age-Range 
===== ========= 
-1  (-1,12) 
12  (-1,12) 
18  (12-17) 
28  (24-34) 
38  (34-44) 
46  (44-54) 
====== ========== 

どんな提案やヘルプは非常に

答えて

2

をおくる。ここで迅速な提案だ、私はそれが役に立てば幸い:

に結果の
case class AgeRange(lowerBound: Int, upperBound: Int) { 
    def contains(value: Int): Boolean = value >= lowerBound && value < upperBound 
} 

val rangeList = List(-1, 12, 17, 24, 34, 44, 54, 64, 100, 1000) 
val ranges = rangeList.sliding(2).map((list => AgeRange(list(0), list(1)))).toList 
val dataset = Seq("-1", "12", "18", "28", "38", "46").toDS 

def findRange(value: Int, ageRanges: List[AgeRange]): Option[AgeRange] = ageRanges.find(_.contains(value)) 

// With UDF 
def myUdf(ageRanges: List[AgeRange]) = udf{ 
    i: Int => findRange(i, ageRanges) 
} 

val result1 = dataset.toDF("age").withColumn("age_range", myUdf(ranges)(col("age").cast("int"))) 

// With map 
val result2 = dataset.map { 
    i: String => (i, findRange(i.toInt, ranges)) 
}.toDF("age", "age_range") 

result1: org.apache.spark.sql.DataFrame = [age: string, age_range: struct<lowerBound: int, upperBound: int>] 
result2: org.apache.spark.sql.DataFrame = [age: string, age_range: struct<lowerBound: int, upperBound: int>] 
+---+---------+ 
|age|age_range| 
+---+---------+ 
| -1| [-1,12]| 
| 12| [12,17]| 
| 18| [17,24]| 
| 28| [24,34]| 
| 38| [34,44]| 
| 46| [44,54]| 
+---+---------+ 
+0

ありがとうダニエル!!! ...それは私のために働いた!!! ... – Bhavesh

1

あなたがUDF関数を使用することができますas

def range = udf((age: String) => { 
    val array = Array(-1, 12, 17, 24, 34, 44, 54, 64, 100, 1000) 
    val ageInt = age.toInt 
    array.filter(i => i <= ageInt).last.toString+"-"+array.filter(i => i > ageInt).head.toString 
}) 

とあなたはあなたが必要とするが、適切なソリューションのためのあなたに十分なアイデア以上のものを与えるべきであるとして、最終的な出力ではありません

+---+---------+ 
|Age|Age-Range| 
+---+---------+ 
|-1 |-1-12 | 
|12 |12-17 | 
|18 |17-24 | 
|28 |24-34 | 
|38 |34-44 | 
|46 |44-54 | 
+---+---------+ 

として出力を持っている必要があり

df.withColumn("Age-Range", range($"Age")) 

として、あなたのデータフレームを呼び出します。

2

ここでは、UDFを使用した簡単な解決方法を示しますが、手動でリストを作成する必要があります。

//dataframe with column age 
val df = spark.sparkContext.parallelize(Seq("-1", "12", "18", "28", "38", "38", "388", "3", "41")).toDF("Age") 

val updateUDF = udf((age : String) => { 
    val range = Seq(
    (-1, 12, "(-1 - 12)"), 
    (12, 17, "(12 - 17)"), 
    (17, 24, "(17 - 24)"), 
    (24, 34, "(24 - 34)"), 
    (34, 44, "(34 - 44)"), 
    (44, 54, "(44 - 54)"), 
    (54, 64, "(54 - 64)"), 
    (64, 10, "(64 - 100)"), 
    (100, 1000, "(100- 1000)") 
) 
range.map(value => { 
    if (age.toInt >= value._1 && age.toInt < value._2) value._3 
    else "" 
}).filter(!_.equals(""))(0) 

}) 

    df.withColumn("Age-Range", updateUDF($"Age")).show(false) 

Here is the output: 
+---+-----------+ 
|Age|Age-Range | 
+---+-----------+ 
|-1 |(-1 - 12) | 
|12 |(12 - 17) | 
|18 |(17 - 24) | 
|28 |(24 - 34) | 
|38 |(34 - 44) | 
|38 |(34 - 44) | 
|388|(100- 1000)| 
|3 |(-1 - 12) | 
|41 |(34 - 44) | 
+---+-----------+ 

私はこれが役立つことを望みます。

+0

ありがとうたくさんの!!! – Bhavesh

関連する問題