根据类似于np.where的字典替换spark数据框中的列值

时间:2019-06-26 07:33:10

标签: python apache-spark pyspark pyspark-sql

我的数据框看起来像-

a = Rules(last_card="As", card = "5c")
print(a.card) -> "5c"
print(a.number)-> "5"
print(a.suit) -> "c"

print("last_card")
**print(a.last_card) -> "As"
print(a.last_card_number) -> "A"
print(a.last_card_suit) -> "s"**

它包含92M条记录。我希望数据框看起来像-

no          city         amount   
1           Kenora        56%
2           Sudbury       23%
3           Kenora        71%
4           Sudbury       41%
5           Kenora        33%
6           Niagara       22%
7           Hamilton      88%

使用python我可以管理它(使用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 ),但在pyspark中没有任何结果。有帮助吗?

我到目前为止已完成-

np.where

为什么给我空值?

1 个答案:

答案 0 :(得分:1)

问题是mapping_expr将为null中未包含的任何城市返回city_dict。快速解决方案是,如果city返回mapping_expr值,则使用coalesce返回null

from pyspark.sql.functions import coalesce

#lookup and replace 
df1= df.withColumn('new_city', coalesce(mapping_expr[df['city']], df['city']))
df1.show()
#+---+--------+------+--------+
#| no|    city|amount|new_city|
#+---+--------+------+--------+
#|  1|  Kenora|   56%|       X|
#|  2| Sudbury|   23%| Sudbury|
#|  3|  Kenora|   71%|       X|
#|  4| Sudbury|   41%| Sudbury|
#|  5|  Kenora|   33%|       X|
#|  6| Niagara|   22%|       X|
#|  7|Hamilton|   88%|Hamilton|
#+---+--------+------+--------+

df1.groupBy('new_city').count().show()
#+--------+-----+
#|new_city|count|
#+--------+-----+
#|       X|    4|
#|Hamilton|    1|
#| Sudbury|    2|
#+--------+-----+

但是,如果替换值之一为null,则上述方法将失败。

在这种情况下,更简单的选择是使用pyspark.sql.DataFrame.replace()

首先使用withColumn创建new_city作为city列中值的副本。

df.withColumn("new_city", df["city"])\
    .replace(to_replace=city_dict.keys(), value=city_dict.values(), subset="new_city")\
    .groupBy('new_city').count().show()
#+--------+-----+
#|new_city|count|
#+--------+-----+
#|       X|    4|
#|Hamilton|    1|
#| Sudbury|    2|
#+--------+-----+