You need to enable JavaScript to run this app. Python中多条件匹配关键词词频高效统计方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

Python中多条件匹配关键词词频高效统计方案咨询

现有代码问题梳理
  1. 逻辑错误:筛选出符合条件的temp数据集后,调用count_words时传入的是全量data,导致统计结果完全不符合预期
  2. 时间复杂度极高:循环逻辑倒置,1500组条件每组都对全量5万条数据做过滤,累计产生7500万次无效计算
  3. 遍历效率极低:使用pandas的iterrows遍历数据,性能比原生Python循环低1~2个数量级,且重复做类型判断和ast.literal_eval转换
  4. 存储结构不合理:将词频统计的defaultdict存在DataFrame单元格中,读写开销远高于直接操作Python字典
优化实现方案

核心思路

把「按条件遍历过滤数据」改为「遍历单次数据匹配所有符合的条件」,将时间复杂度从O(N*M)(N为数据量,M为条件组数)降到O(N)

优化后代码

from collections import defaultdict
import pandas as pd
import ast
import datetime
from pathlib import PurePath

# ========== 1. 预生成条件查询字典 ==========
cat_ids = [subcats['id'] for subcats in cp.cat_config['cat'].values()]
# 原有多索引生成逻辑保留
index = pd.MultiIndex.from_product([cat_ids, data.code.unique(), [start_date.strftime("%Y%m%d")], 
    data.target.unique(), [datetime.datetime.strptime(str(data._dates.unique()[0]), 
    "%Y%m%d").date().isocalendar()[1]]], names=["category_code", "region_code", "start_date",  
    "target", "year_week"])
top_word_id = pd.DataFrame(index=index).reset_index()

# 把条件转成字典,key为(分类id, target, 区域code),value为对应词频统计对象
cond_map = {}
for idx, row in top_word_id.iterrows():
    key = (row['category_code'], row['target'], row['region_code'])
    cond_map[key] = {
        'rel': defaultdict(int),
        'pos': defaultdict(int),
        'neg': defaultdict(int)
    }

# 定义列表类型转换函数,读数据时一次性转换
def parse_list(x):
    return ast.literal_eval(x) if isinstance(x, str) else x

# ========== 2. 遍历日期处理数据 ==========
while dates_queue:
    date = dates_queue.popleft()
    date_str = date.strftime("%Y%m%d.tsv")
    # 读数据时直接完成单词列的类型转换,避免后续重复处理
    data = pd.read_csv(
        PurePath("../results", date_str), 
        sep='\t', 
        engine='python', 
        encoding='utf-8',
        converters={'1': parse_list, '2': parse_list, '3': parse_list}
    )

    # 单次遍历全量数据,匹配所有符合条件的分组直接累加词频
    for _, row in data.iterrows():
        row_target = row['target']
        row_code = row['code']
        # 遍历所有分类,匹配符合的条件组
        for cat_id in cat_ids:
            if row[cat_id] != 1:
                continue
            current_key = (cat_id, row_target, row_code)
            if current_key not in cond_map:
                continue
            # 直接累加三类词频
            for w in row['1']:
                cond_map[current_key]['pos'][w] += 1
            for w in row['2']:
                cond_map[current_key]['neg'][w] += 1
            for w in row['3']:
                cond_map[current_key]['rel'][w] += 1

# ========== 3. 把结果写回top_word_id(如果需要保留原有结构) ==========
for idx, row in top_word_id.iterrows():
    key = (row['category_code'], row['target'], row['region_code'])
    res = cond_map[key]
    top_word_id.at[idx, 'weekly_associated_top_word'] = res['rel']
    top_word_id.at[idx, 'weekly_positive_top_word'] = res['pos']
    top_word_id.at[idx, 'weekly_negative_top_word'] = res['neg']

性能提升说明

  • 修正了原代码统计全量数据的逻辑错误,结果符合预期
  • 去掉了1500次重复过滤全量数据的操作,仅需一次遍历即可完成所有分组统计
  • 读数据时一次性完成类型转换,避免后续重复判断和调用ast.literal_eval
  • 用Python字典做条件查询,读写速度比存DataFrame单元格提升10倍以上
  • 整体运行速度预计可提升数十到上百倍,单份5万条数据的处理耗时可降到秒级

内容的提问来源于stack exchange,提问作者Inhyeok Yoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 01:30:03