我有一个Spark Dataframe,它有一列包含字符串。这些字符串引用的是饮料,但也可以包括数量/体积等(没有一致性,因此正则表达式可以帮助解决此问题,但无法解决此问题(。为了避免这种情况,我希望使用过滤器来确定是否在列表中找到列字符串,然后用布尔值生成一个新列,但不确定这样做的最佳方法。
我尝试使用case-when
逻辑,但没有成功。
我更喜欢contains
,因为它可以解释isin
所需要的不完全匹配。
data = [
[
1,
"SODA",
],
[
2,
"JUICE 1L",
],
[
3,
"WATER 64OZ",
],
[
4,
"HOT TEA",
],
]
df = pd.DataFrame(data, columns=["ID", "Beverage"])
DRINK_LIST = ["SODA", "WATER", "COFFEE", "TEA", "JUICE"]
sdf = spark.createDataFrame(df)
有人知道最好的方法吗?
假设这是您的饮料数组(或列表(:
val drinks = Array("SODA", "WATER", "COFFEE", "TEA", "JUICE")
我们可以将其转换为regex表达式,以便将其应用于rlike
API:
val regex = drinks.map(x => "(" + x + ")").mkString("|").toLowerCase()
得到CCD_ 5。
然后,我们可以将其应用于数据集,例如:
df = df.withColumn("is_within", rlike(lower(beverage), regex))
PS:将列转换为小写,但也转换为列表,只是为了确保所有内容都兼容。
我宁愿使用rlike
而不是contains
,因为我不确定我们是否可以在不进行单独检查的情况下使用后者来获得相同的结果。
祝你好运!
%python
import pandas as pd
import pyspark.sql.functions as py
data = [[1, 'SODA'], [2, 'JUICE'], [3, 'WATER'], [4, 'HOT STEA']]
df = pd.DataFrame(data, columns=['ID', 'Beverage'])
sdf = spark.createDataFrame(df)
sdf.show()
DRINK_LIST = ["SODA", "WATER", "COFFEE", "TEA", "JUICE"]
# May need upper or lowercase conversion. Different to scala api.
sdf = sdf.withColumn('check', py.when(py.length(py.regexp_extract('Beverage', '(?=^|s)(' + '|'.join(DRINK_LIST) + ')(?=s|$)', 0)) > 0, True).otherwise(False))
sdf.show()
退货:
+---+--------+-----+
| ID|Beverage|check|
+---+--------+-----+
| 1| SODA| true|
| 2| JUICE| true|
| 3| WATER| true|
| 4|HOT STEA|false|
+---+--------+-----+