У меня есть 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
-
# Efficient (pseudocode 1)
if country == 'Ireland':
if length(postcode) == 4:
postcode = '0'+postcode # Append 0 to postcode incase it's 4 digit.
if bloodgroup == null:
bloodgroup = 'Unknown'
Как вы можете видеть в псевдокоде выше, проверка 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'
два раза.Я проверил executionPlan
, используя df.explain()
, и он не выполняет автоматическую оптимизацию, что, как я думал, может сделать катализатор.
Как мы можем написать PySpark
код, соответствующий псевдокоду 1, где мы проверяем страну один раз, а затем проверяем 2 условия?