为简单起见,我有一个具有以下架构的df:
root
|-- Event_Time: string (nullable = true)
|-- tokens: array (nullable = true)
| |-- element: string (containsNull = true)
“令牌”的某些元素具有数字和特殊字符,例如:
"431883", "r2b2", "@refe98"
以任何方式我都可以删除所有这些内容并仅保留实际单词?我想稍后再进行LDA,并希望之前清除我的数据。
我尝试了regexp_replace
,explode
,str.replace
,但都没有成功,也许我没有正确使用它们。
谢谢
edit2:
df_2 = (df_1.select(explode(df_1.tokens).alias('elements'))
.select(regexp_replace('elements','\\w*\\d\\w**',""))
)
这仅在字符串类型的列中有效,并且使用explode方法,我可以将数组分解为字符串,但不再存在同一行中了...有人可以对此进行改进吗?
答案 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**')) """))