Sae*_*ili 4 python-3.x pyspark
假设我们有一个 pyspark 数据框,其中一列 ( column_a) 包含一些字符串值,并且还有一个字符串列表 ( list_a)。
数据框:
column_a | count
some_string | 10
another_one | 20
third_string | 30
Run Code Online (Sandbox Code Playgroud)
列表_a:
['string', 'third', ...]
Run Code Online (Sandbox Code Playgroud)
如果 column_a 的值包含 list_a 的项目之一,我想过滤此数据框并仅保留行。
这是用于column_a基于单个字符串过滤的代码:
df['column_a'].like('%string_value%')
Run Code Online (Sandbox Code Playgroud)
但是,对于字符串列表,我们如何获得相同的结果呢?(保留 column_a 的值为 'string'、'third' 的行,...)
IIUC,要返回其行column_a“就像是”(在SQL意义上)的任何值中list_a。
一种方法是使用functools.reduce:
from functools import reduce
list_a = ['string', 'third']
df1 = df.where(
reduce(lambda a, b: a|b, (df['column_a'].like('%'+pat+"%") for pat in list_a))
)
df1.show()
#+------------+-----+
#| column_a|count|
#+------------+-----+
#| some_string| 10|
#|third_string| 30|
#+------------+-----+
Run Code Online (Sandbox Code Playgroud)
本质上,您遍历所有可能的字符串以list_a进行比较like并对结果进行“或”运算。下面是执行计划:
df1.explain()
#== Physical Plan ==
#*(1) Filter (Contains(column_a#0, string) || Contains(column_a#0, third))
#+- Scan ExistingRDD[column_a#0,count#1]
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用pyspark.sql.Column.rlike而不是like.
df2 = df.where(
df['column_a'].rlike("|".join(["(" + pat + ")" for pat in list_a]))
)
df2.show()
#+------------+-----+
#| column_a|count|
#+------------+-----+
#| some_string| 10|
#|third_string| 30|
#+------------+-----+
Run Code Online (Sandbox Code Playgroud)
其中有对应的执行计划:
df2.explain()
#== Physical Plan ==
#*(1) Filter (isnotnull(column_a#0) && column_a#0 RLIKE (string)|(third))
#+- Scan ExistingRDD[column_a#0,count#1]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7370 次 |
| 最近记录: |