Pyspark数据框-将字符串映射到数值

Bri*_*ehe 1 apache-spark apache-spark-sql pyspark spark-dataframe pyspark-sql

我正在寻找一种转换给定数据列(在这种情况下为字符串)并将其转换为数字表示形式的方法。例如,我有一个带有值的字符串数据框:

+------------+
|    level   |
+------------+
|      Medium|
|      Medium|
|      Medium|
|        High|
|      Medium|
|      Medium|
|         Low|
|         Low|
|        High|
|         Low|
|         Low|
Run Code Online (Sandbox Code Playgroud)

我想创建一个新列,将这些值转换为:

"High"= 1, "Medium" = 2, "Low" = 3

+------------+
|   level_num|
+------------+
|           2|
|           2|
|           2|
|           1|
|           2|
|           2|
|           3|
|           3|
|           1|
|           3|
|           3|
Run Code Online (Sandbox Code Playgroud)

我试图定义一个函数,并像这样在数据框上进行foreach:

def f(x): 
    if(x == 'Medium'):
       return 2
    elif(x == "Low"):
       return 3
    else:
       return 1

 a = df.select("level").rdd.foreach(f)
Run Code Online (Sandbox Code Playgroud)

但这将返回“无”类型。有什么想法吗?与往常一样感谢您的帮助!

des*_*aut 5

您当然可以按照您尝试的方式进行map操作-您将需要一个操作而不是foreach

spark.version
# u'2.2.0'

from pyspark.sql import Row
# toy data:
df = spark.createDataFrame([Row("Medium"),
                              Row("High"),
                              Row("High"),
                              Row("Low")
                             ],
                              ["level"])
df.show()
# +------+ 
# | level|
# +------+
# |Medium|
# |  High|
# |  High|
# |   Low|
# +------+
Run Code Online (Sandbox Code Playgroud)

使用您f(x)的这些玩具数据,我们将获得:

df.select("level").rdd.map(lambda x: f(x[0])).collect()
# [2, 1, 1, 3]
Run Code Online (Sandbox Code Playgroud)

还有一个map将为您提供一个数据框:

df.select("level").rdd.map(lambda x: f(x[0])).map(lambda x: Row(x)).toDF(["level_num"]).show()
# +---------+ 
# |level_num|
# +---------+
# |        2|
# |        1|
# |        1| 
# |        3|
# +---------+
Run Code Online (Sandbox Code Playgroud)

但是最好使用dataframe函数when而不是您的方法而不调用临时中间RDD来执行此操作f(x)

from pyspark.sql.functions import col, when

df.withColumn("level_num", when(col("level")=='Medium', 2).when(col("level")=='Low', 3).otherwise(1)).show()
# +------+---------+ 
# | level|level_num|
# +------+---------+
# |Medium|        2|
# |  High|        1| 
# |  High|        1|
# |   Low|        3| 
# +------+---------+    
Run Code Online (Sandbox Code Playgroud)