当列表值匹配 Pyspark 数据框中列值的子字符串时填充新列

Use*_*345 3 python apache-spark pyspark

我有一个Pyspark如下所示的数据框

df.show()

+---+----------------------+
| id|                   con|
+---+----------------------+
|  3|           mac,mac pro|
|  1|        iphone5,iphone|
|  1| android,android phone|
|  1|    windows,windows pc|
|  1| spy camera,spy camera|
|  2|               camera,|
|  3|             cctv,cctv|
|  2|   apple iphone,iphone|
|  3|           ,spy camera|
+---+----------------------+
Run Code Online (Sandbox Code Playgroud)

我想基于某些lists. 名单如下

phone_list = ['iphone', 'android', 'nokia']
pc_list = ['windows', 'mac']
Run Code Online (Sandbox Code Playgroud)

Condition:

if a element in a list matches a string/substring in a column then flag the column to the value of that particular list
Run Code Online (Sandbox Code Playgroud)

基本上我想要的是phone_list我有元素,iphone所以应该匹配id 1where conisiphone5, iphone和 flag asphones等等。

Expected result

+---+----------------------+------+----+
| id|                   con|   cat| abc|
+---+----------------------+------+----+
|  3|           mac,mac pro|  null|  pc|
|  1|        iphone5,iphone|phones|null|
|  1| android,android phone|phones|null|
|  1|    windows,windows pc|  null|  pc|
|  1| spy camera,spy camera|  null|null|
|  2|               camera,|  null|null|
|  3|             cctv,cctv|  null|null|
|  2|   apple iphone,iphone|phones|null|
|  3|           ,spy camera|  null|null|
+---+----------------------+------+----+
Run Code Online (Sandbox Code Playgroud)

我做了如下。

df1 = df.withColumn('cat', F.when(df.con.isin(phone_list), 'phones')).withColumn('abc', F.when(df.con.isin(pc_list), 'pc'))
Run Code Online (Sandbox Code Playgroud)

output

df1.show()

+---+----------------------+----+----+
| id|                   con| cat| abc|
+---+----------------------+----+----+
|  3|           mac,mac pro|null|null|
|  1|        iphone5,iphone|null|null|
|  1| android,android phone|null|null|
|  1|    windows,windows pc|null|null|
|  1| spy camera,spy camera|null|null|
|  2|               camera,|null|null|
|  3|             cctv,cctv|null|null|
|  2|   apple iphone,iphone|null|null|
|  3|           ,spy camera|null|null|
+---+----------------------+----+----+
Run Code Online (Sandbox Code Playgroud)

我怎样才能以正确的方式进行这种类型的比较?

小智 5

最好的方法是避免使用udf和使用pyspark.sql.Column.rlike(). True如果该列与参数中包含的正则表达式匹配,这将返回。

在这种情况下,您可以使用"|".join(list_of_terms)创建一个正则表达式模式来匹配列表中的任何单词。("|"OR运算符)

from pyspark.sql.functions import col, when

df.select(
    "*", 
    when(col("con").rlike("|".join(phone_list)), "phones").alias("cat"), 
    when(col("con").rlike("|".join(pc_list)), "pc").alias("abc")
).show(truncate=False)
#+---+---------------------+------+----+
#|id |con                  |cat   |abc |
#+---+---------------------+------+----+
#|3  |mac,mac pro          |null  |pc  |
#|1  |iphone5,iphone       |phones|null|
#|1  |android,android phone|phones|null|
#|1  |windows,windows pc   |null  |pc  |
#|1  |spy camera,spy camera|null  |null|
#|2  |camera,              |null  |null|
#|3  |cctv,cctv            |null  |null|
#|2  |apple iphone,iphone  |phones|null|
#|3  |,spy camera          |null  |null|
#+---+---------------------+------+----+
Run Code Online (Sandbox Code Playgroud)

我们还使用了如果未指定任何条件pyspark.sql.functions.when()将返回的事实。nullotherwise()