当列表值与Pyspark数据帧中的列值的子字符串匹配时,填充新列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当列表值与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|
+---+----------------------+
我想基于某些lists
创建新列。列表如下
phone_list = ['iphone', 'android', 'nokia']
pc_list = ['windows', 'mac']
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
基本上我想要的是在phone_list
我有元素iphone
所以应该匹配id
1
其中con
是iphone5, iphone
和旗帜为phones
等等。
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|
+---+----------------------+------+----+
我在下面做了。
df1 = df.withColumn('cat', F.when(df.con.isin(phone_list), 'phones')).withColumn('abc', F.when(df.con.isin(pc_list), 'pc'))
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|
+---+----------------------+----+----+
我怎样才能以正确的方式进行这种比较?
答案
最好的方法是避免使用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|
#+---+---------------------+------+----+
如果没有指定pyspark.sql.functions.when()
条件,我们也使用null
将返回otherwise()
的事实。
另一答案
定义udf
函数以检查con
列中包含的字符串列表应该可以获得所需的输出
phone_list = ['iphone', 'android', 'nokia']
pc_list = ['windows', 'mac']
from pyspark.sql import functions as f
from pyspark.sql import types as t
def checkIsIn(con):
phones = None
pc = None
for x in phone_list:
if(x in con):
phones = 'phones'
for x in pc_list:
if x in con:
pc = 'pc'
return (phones, pc)
checkIsInUdf = f.udf(checkIsIn, t.StructType([t.StructField('cat', t.StringType(), True), t.StructField('abc', t.StringType(), True)]))
df.withColumn('temp', checkIsInUdf(f.col('con')))
.select(f.col('id'), f.col('con'), f.col('temp.*'))
.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|
+---+---------------------+------+----+
我希望答案是有帮助的
以上是关于当列表值与Pyspark数据帧中的列值的子字符串匹配时,填充新列的主要内容,如果未能解决你的问题,请参考以下文章
pyspark:删除作为另一列值的子字符串,并从给定列的值中包含正则表达式字符