在PySp中使用IfElse的有效方法

2024-09-28 03:19:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个DataFrame下面-

from pyspark.sql.functions import col, when, length, lit, concat
values = [(1,'USA','12424','AB+'),(2,'Japan','63252','B-'),(3,'Ireland','23655',None),(4,'France','57366','O+'),
          (5,'Ireland','82351','A-'),(6,'USA','35854','B+'),(7,'Ireland','5835','AB-'),(8,'USA','95255','B+')]
df = sqlContext.createDataFrame(values,['id','country','postcode','bloodgroup'])
df.show()
+---+-------+--------+----------+
| id|country|postcode|bloodgroup|
+---+-------+--------+----------+
|  1|    USA|   12424|       AB+|
|  2|  Japan|   63252|        B-|
|  3|Ireland|   23655|      null|
|  4| France|   57366|        O+|
|  5|Ireland|   82351|        A-|
|  6|    USA|   35854|        B+|
|  7|Ireland|    5835|       AB-|
|  8|    USA|   95255|        B+|
+---+-------+--------+----------+

我需要根据以下条件对postcode&;bloodgroup列进行更改,如本文中总结的python pseudocode-

^{pr2}$

正如您在上面的伪代码中看到的,检查country == 'Ireland'只执行了一次,因为它是两个条件中的一个公共子句。使用and将此子句与其他两个条件耦合起来进行另一种操作将是低效的-

# Inefficient (pseudocode 2)
if country == 'Ireland' and length(postcode) == 4:
        postcode = '0'+postcode   
if country == 'Ireland' and bloodgroup == null: 
        bloodgroup = 'Unknown'

我正在使用PySpark,我知道如何做到这一点的唯一方法是-

df = df.withColumn('postcode',when((col('country') == 'Ireland') & (length(col('postcode')) == 4),concat(lit('0'),col('postcode'))).otherwise(col('postcode')))
df = df.withColumn('bloodgroup',when((col('country') == 'Ireland') & col('bloodgroup').isNull(),'Unknown').otherwise(col('bloodgroup')))
df.show()
+---+-------+--------+----------+
| id|country|postcode|bloodgroup|
+---+-------+--------+----------+
|  1|    USA|   12424|       AB+|
|  2|  Japan|   63252|        B-|
|  3|Ireland|   23655|   Unknown|
|  4| France|   57366|        O+|
|  5|Ireland|   82351|        A-|
|  6|    USA|   35854|        B+|
|  7|Ireland|   05835|       AB-|
|  8|    USA|   95255|        B+|
+---+-------+--------+----------+

但是,这与我上面写的低效伪代码相对应,因为我们检查了country == 'Ireland'两次。我使用df.explain()检查了executionPlan,它没有进行任何自动优化,我认为catalyst可能会这样做。在

我们如何编写一个对应于伪代码1的PySpark代码,在这里我们只检查一次国家,然后测试这两个条件?在


Tags: 代码iddfabcol条件countrylength

热门问题