PySpark 中的正则表达式

Posted

技术标签:

【中文标题】PySpark 中的正则表达式【英文标题】:regexp in PySpark 【发布时间】:2015-07-14 16:10:55 【问题描述】:

我正在尝试在 pyspark 中重现 django ORM 查询的结果:

social_filter = '(facebook|flipboard|linkedin|pinterest|reddit|twitter)'
Collection.objects.filter(social__iregex=social_filter)

我的主要问题是它应该不区分大小写。

我试过这个:

social_filter = "social ILIKE 'facebook' OR social ILIKE 'flipboard' OR social ILIKE 'linkedin' OR social ILIKE 'pinterest' OR social ILIKE 'reddit' OR social ILIKE 'twitter'"
df = sessions.filter(social_filter)

导致以下错误:

Py4JJavaError: An error occurred while calling o31.filter.
: java.lang.RuntimeException: [1.22] failure: end of input expected

social ILIKE 'facebook' OR social ILIKE 'flipboard' OR social ILIKE 'linkedin' OR social ILIKE 'pinterest' OR social ILIKE 'reddit' OR social ILIKE 'twitter'

还有下面的表达式:

social_filter = "social  ~* (facebook|flipboard|linkedin|pinterest|reddit|twitter)"
df = sessions.filter(social_filter)

崩溃了:

Py4JJavaError: An error occurred while calling o31.filter.
: java.lang.RuntimeException: [1.17] failure: identifier expected

social  ~* (facebook|flipboard|linkedin|pinterest|reddit|twitter)
       ^
    at scala.sys.package$.error(package.scala:27)
    at org.apache.spark.sql.catalyst.SqlParser.parseExpression(SqlParser.scala:45)
    at org.apache.spark.sql.DataFrame.filter(DataFrame.scala:652)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

请帮忙!

【问题讨论】:

【参考方案1】:

以下内容如何:

>>> rdd = sc.parallelize([Row(name='bob', social='TWITter'), 
                          Row(name='steve', social='facebook')])
>>> df = sqlContext.createDataFrame(rdd)
>>> df.where("LOWER(social) LIKE 'twitter'").collect()
[Row(name=u'bob', social=u'TWITter')]

如果您需要实际的正则表达式,您可以对所有想要的社交网络执行此操作。否则,如果匹配准确,您可以执行以下操作:

>>> df.where("LOWER(social) IN ('twitter', 'facebook')").collect()
[Row(name=u'bob', social=u'TWITter'), Row(name=u'steve', social=u'facebook')]

【讨论】:

【参考方案2】:

您现在也可以使用 UDF:

from pyspark.sql import functions as F
from pyspark.sql.types import BooleanType
import re as re

def filter_fn(s):
     return re.search('(facebook|flipboard|linkedin|pinterest|reddit|twitter)', s, re.IGNORECASE) is not None


filter_udf = F.udf(filter_fn, BooleanType())

sessions_filtered = sessions.filter(filter_udf(sessions['social']))

【讨论】:

以上是关于PySpark 中的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

pyspark 中的正则表达式来检查字母和空格(也可以使用 uni 代码)

如何替换/删除 PySpark RDD 中的正则表达式?

Pyspark:UDF 将正则表达式应用于数据帧中的每一行

如何通过 Pyspark 中同一数据框中另一列的正则表达式值过滤数据框中的一列

如何使用正则表达式从 PySpark databricks 笔记本中的文件中解析表名

使用 pyspark 中的正则表达式将数字添加到字符串中最后一个字符之前的字符串