Python 基于类似于np.where的字典替换spark dataframe中的列值

Python 基于类似于np.where的字典替换spark dataframe中的列值,python,apache-spark,pyspark,pyspark-sql,Python,Apache Spark,Pyspark,Pyspark Sql,我的数据框看起来像- no city amount 1 Kenora 56% 2 Sudbury 23% 3 Kenora 71% 4 Sudbury 41% 5 Kenora 33% 6 Niagara 22% 7 Hamilton

我的数据框看起来像-

no          city         amount   
1           Kenora        56%
2           Sudbury       23%
3           Kenora        71%
4           Sudbury       41%
5           Kenora        33%
6           Niagara       22%
7           Hamilton      88%
no          city         amount      new_city
1           Kenora        56%           X
2           Niagara       23%           X       
3           Kenora        71%           X
4           Sudbury       41%           Sudbury       
5           Ottawa        33%           Ottawa
6           Niagara       22%           X
7           Hamilton      88%           Hamilton
它由9200万条记录组成。我希望我的数据框看起来像-

no          city         amount   
1           Kenora        56%
2           Sudbury       23%
3           Kenora        71%
4           Sudbury       41%
5           Kenora        33%
6           Niagara       22%
7           Hamilton      88%
no          city         amount      new_city
1           Kenora        56%           X
2           Niagara       23%           X       
3           Kenora        71%           X
4           Sudbury       41%           Sudbury       
5           Ottawa        33%           Ottawa
6           Niagara       22%           X
7           Hamilton      88%           Hamilton
使用python我可以管理它(使用
np.where
),但在pyspark中不会得到任何结果。有什么帮助吗

到目前为止,我已经做了-

#create dictionary
city_dict = {'Kenora':'X','Niagara':'X'}

mapping_expr  = create_map([lit(x) for x in chain(*city_dict .items())])

#lookup and replace 
df= df.withColumn('new_city', mapping_expr[df['city']])

#But it gives me wrong results.

df.groupBy('new_city').count().show()

new_city    count
   X          2
  null        3

为什么给我空值?

问题是
mapping\u expr
将为
city\u dict
中未包含的任何城市返回
null
。如果
mapping\u expr
返回
null
值,则可使用快速修复方法返回
city

来自pyspark.sql.functions的
导入合并
#查找和替换
df1=df.withColumn('new_city',coalesce(映射表达式[df['city']],df['city']))
df1.show()
#+---+--------+------+--------+
#|否|城市|金额|新城|
#+---+--------+------+--------+
#|1 |凯诺拉| 56%| X|
#|2 |萨德伯里| 23%|萨德伯里|
#|3 |凯诺拉| 71%| X|
#|4 |萨德伯里| 41%|萨德伯里|
#|5 |凯诺拉| 33%| X|
#|6 |尼亚加拉| 22%| X|
#|7 |汉密尔顿| 88%|汉密尔顿|
#+---+--------+------+--------+
df1.groupBy('new_city').count().show()
#+--------+-----+
#|新市镇|计数|
#+--------+-----+
#|X | 4|
#|汉密尔顿| 1|
#|萨德伯里| 2|
#+--------+-----+
但是,如果其中一个替换值为
null
,则上述方法将失败

在这种情况下,一个更容易的选择可能是使用:

首先使用
with column
创建
新城市
,作为
城市
列中值的副本

df.withColumn(“新城市”,df[“城市])\
.replace(to_replace=city\u dict.keys(),value=city\u dict.values(),subset=“new\u city”)\
.groupBy('new_city').count().show()
#+--------+-----+
#|新市镇|计数|
#+--------+-----+
#|X | 4|
#|汉密尔顿| 1|
#|萨德伯里| 2|
#+--------+-----+