将列的不同值间隔映射为整数

时间:2018-05-21 09:53:49

标签: apache-spark dataframe

我在Spark中有一个数据框:

customer  |   age
--------------------
    A         25
    B         17
    C         8

客户和年龄列都是字符串类型。

所以,

  • 如果(0>=age<=10),那么我想将其映射到0
  • 如果(11>=age<=20),那么我想将其映射到1
  • 如果(21>=age<=30),那么我想将其映射到2

使新数据框成为:

customer_new  |   age_new
--------------------
    A         2    
    B         1    
    C         0

此处新数据框customer_new的类型为Stringage_new的类型为Integer

3 个答案:

答案 0 :(得分:0)

您可以使用withColumn多个when功能来提供条件。请尝试以下代码,

df.withColumn("customer_new", $"customer")
  .withColumn("age_new",
    when($"age" >= 0 && $"age" <= 10, 0).
      when($"age" >= 11 && $"age" <= 20, 1).
      when($"age" >= 21 && $"age" <= 30, 2)).
  select("customer_new", "age_new").show()

它会给你以下输出

+------------+-------+
|customer_new|age_new|
+------------+-------+
|           A|      2|
|           B|      1|
|           C|      0|
+------------+-------+

答案 1 :(得分:-1)

第一步是将列类型转换为double。

val df = Seq(("a", "25"), ("b", "17"), ("c", "8")).toDF("customer", "age")
  .withColumn("age", $"age".cast(DoubleType)) 

然后,如果您只有几个条件,则可以使用whenotherwise。例如,使用输入数据和条件:

val df2 = df.withColumn("age_new", 
  when($"age" <= 10, 0.0).
  when($"age" <= 20, 1.0).
  when($"age" <= 30, 2.0).
  otherwise(3.0))

如果有很多条件,那么使用when会很烦人。在这种情况下,Bucketizer是一个很好的选择:

val splits = Array(0.0, 10.0, 20.0, 30.0)
val bucketizer = new Bucketizer().setInputCol("age").setOutputCol("age_new").setSplits(splits)
val df3 = bucketizer.transform(df)

两种情况下的输出相同(age列可以使用selectdrop删除:

+--------+----+-------+
|customer| age|age_new|
+--------+----+-------+
|       a|25.0|    2.0|
|       b|17.0|    1.0|
|       c| 8.0|    0.0|
+--------+----+-------+

答案 2 :(得分:-1)

始终建议尽可能使用内置函数。由于其他人已经建议过功能,您可以尝试使用地图功能

import sqlContext.implicits._
df.map(row => {
  val age = row.getAs[String]("age").trim.toInt
  (row.getAs[String]("customer"), if(age >= 0 && age <= 10) "0" else if(age >= 11 && age <= 20) "1" else if(age >= 21 && age <= 30) "2" else null)
})
  .toDF("customer_new", "age_new")

应该给你

+------------+-------+
|customer_new|age_new|
+------------+-------+
|A           |2      |
|B           |1      |
|C           |0      |
+------------+-------+