You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检查字符串子串是否在字典键中及PySpark相关技术咨询

嘿,我给你拆解一下这几个问题哈!

一、处理部分字符串匹配与忽略大小写

不管是遇到"Mexican Pepper"这种包含关键词的项,还是"Tomato"和"tomato"这种大小写差异的情况,核心思路是统一文本格式+子串/正则匹配。

1. 基础实现:统一大小写+子串匹配

先把字典里的关键词和输入项都转成小写,消除大小写差异;然后检查输入项的小写形式是否包含某个类别下的关键词(同样转小写)。

假设你的类别字典是这样的(可以替换成你自己的):

category_dict = {
    "fruit": ["apple", "banana"],
    "vegetable": ["pepper"],
    "junk food": ["pizza"]
}
grocery_list = ["apple","bananas","pizza","pepper", "Mexican Pepper", "tomato"]

对应的处理代码:

# 先把字典里的关键词全部转小写,方便后续统一比对
lowercase_category_map = {
    cat: [kw.lower() for kw in keywords] 
    for cat, keywords in category_dict.items()
}

def get_item_category(item):
    item_lower = item.lower()
    # 遍历每个类别,检查是否有匹配的关键词
    for category, keywords in lowercase_category_map.items():
        for keyword in keywords:
            if keyword in item_lower:
                return category
    # 没有匹配到就返回默认类别,比如"unknown"
    return "unknown"

# 测试一下效果
for item in grocery_list:
    print(f"{item} → {get_item_category(item)}")

运行后会输出:

apple → fruit
bananas → fruit
pizza → junk food
pepper → vegetable
Mexican Pepper → vegetable
tomato → unknown

2. 进阶优化:正则表达式匹配

如果你的关键词比较复杂(比如带特殊字符、需要更灵活的匹配规则),可以用正则表达式,结合re.IGNORECASE参数直接忽略大小写:

import re

# 为每个类别构建正则模式,匹配该类别下的任意关键词
category_regex_map = {
    cat: re.compile('|'.join(keywords), re.IGNORECASE)
    for cat, keywords in category_dict.items()
}

def get_item_category_regex(item):
    for category, pattern in category_regex_map.items():
        if pattern.search(item):
            return category
    return "unknown"

# 测试效果和基础版一致
for item in grocery_list:
    print(f"{item} → {get_item_category_regex(item)}")
二、统计各类别出现次数

结合上面的分类函数,用collections.Counter就能轻松统计:

from collections import Counter

category_counter = Counter()
for item in grocery_list:
    category = get_item_category(item)
    category_counter[category] += 1

print("类别统计结果:", category_counter)
# 输出:类别统计结果: Counter({'fruit': 2, 'vegetable': 2, 'junk food': 1, 'unknown': 1})
三、关于PySpark的使用

当然可以用PySpark来处理!尤其是当你的购物清单数据量极大(比如百万级甚至更多),PySpark的分布式处理能力能帮你高效完成任务。

这里给你两种实现思路:

1. 用UDF(用户自定义函数)实现

适合逻辑复杂的场景,把类别字典做成广播变量(避免每个节点都复制一份,节省资源):

from pyspark.sql import SparkSession
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

# 初始化Spark会话
spark = SparkSession.builder.appName("GroceryCategoryAnalysis").getOrCreate()

# 把购物清单转成Spark DataFrame
grocery_df = spark.createDataFrame(
    [("apple",), ("bananas",), ("pizza",), ("pepper",), ("Mexican Pepper",), ("tomato",)],
    ["item"]
)

# 广播类别字典
broadcast_category = spark.sparkContext.broadcast(category_dict)

# 定义UDF函数
@udf(StringType())
def get_category_spark(item):
    item_lower = item.lower()
    for cat, keywords in broadcast_category.value.items():
        for kw in keywords:
            if kw.lower() in item_lower:
                return cat
    return "unknown"

# 添加类别列并统计
result_df = grocery_df.withColumn("category", get_category_spark(grocery_df["item"]))
result_df.groupBy("category").count().show()

执行后会输出:

+-----------+-----+
|   category|count|
+-----------+-----+
|      fruit|    2|
|junk food  |    1|
|  vegetable|    2|
|    unknown|    1|
+-----------+-----+

2. 用Spark内置函数实现(性能更优)

如果逻辑简单,尽量用Spark内置函数,避免UDF的性能开销:

from pyspark.sql.functions import lower, regexp_extract, when

# 构建正则模式,分组对应不同类别
pattern = r"(apple|banana)|(pepper)|(pizza)"
result_df = grocery_df.withColumn(
    "category",
    when(regexp_extract(lower(grocery_df["item"]), pattern, 1) != "", "fruit")
    .when(regexp_extract(lower(grocery_df["item"]), pattern, 2) != "", "vegetable")
    .when(regexp_extract(lower(grocery_df["item"]), pattern, 3) != "", "junk food")
    .otherwise("unknown")
)

result_df.groupBy("category").count().show()

这个方法和UDF的结果一致,但在大数据量下速度更快。

内容的提问来源于stack exchange,提问作者A.Dorra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:13:03