Pyspark:从字符串数组中删除特殊/数字字符串

时间:2018-08-06 11:16:51

标签: python regex string apache-spark pyspark

为简单起见,我有一个具有以下架构的df:

root

 |-- Event_Time: string (nullable = true)

 |-- tokens: array (nullable = true)

 |    |-- element: string (containsNull = true)

“令牌”的某些元素具有数字和特殊字符,例如:

 "431883", "r2b2", "@refe98"

以任何方式我都可以删除所有这些内容并仅保留实际单词?我想稍后再进行LDA,并希望之前清除我的数据。 我尝试了regexp_replaceexplodestr.replace,但都没有成功,也许我没有正确使用它们。 谢谢

edit2:

df_2 = (df_1.select(explode(df_1.tokens).alias('elements'))
          .select(regexp_replace('elements','\\w*\\d\\w**',""))
      )

这仅在字符串类型的列中有效,并且使用explode方法,我可以将数组分解为字符串,但不再存在同一行中了...有人可以对此进行改进吗?

3 个答案:

答案 0 :(得分:1)

我找到的解决方案是(也可以在评论部分中由pault指出):

在标记爆炸后,我通过收集列表进行分组和聚集,以我想要的格式取回标记。

以下是关于保管箱的评论: 爆炸之后,您需要对groupBy进行分组并与collect_list聚合,以将值返回到单行中。假设Event_Time是唯一键:

df2 = df_1
    .select("Event_Time", regexp_replace(explode("tokens"), "<your regex here>")        
    .alias("elements")).groupBy("Event_Time")
    .agg(collect_list("elements").alias("tokens")) 

此外,我不知道的保罗说,如果不使用udf或rdd,目前无法在pyspark中的数组上进行迭代。

答案 1 :(得分:0)

from pyspark.sql.functions import *
df = spark.createDataFrame([(["@a", "b", "c"],), ([],)], ['data'])
df_1 = df.withColumn('data_1', concat_ws(',', 'data'))
df_1 = df_1.withColumn("data_2", regexp_replace('data_1', "['{@]",""))
#df_1.printSchema()
df_1.show()

+----------+------+------+
|      data|data_1|data_2|
+----------+------+------+
|[@a, b, c]|@a,b,c| a,b,c|
|        []|      |      |
+----------+------+------+

答案 2 :(得分:0)

The transform() function was added in PySpark 3.1.0,它帮助我更轻松地完成了这项任务。问题中的示例现在看起来像这样:

from pyspark.sql import functions as F

df_2 = df_1.withColumn("tokens", 
                F.expr(""" transform(tokens, x -> regexp_replace(x, '\\w*\\d\\w**')) """))