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

如何在Polars方法链中实现多文本列的分组HTML标签统计(替代循环拼接方案)

如何在Polars方法链中实现多文本列的分组HTML标签统计(替代循环拼接方案)

嘿,这个需求我太懂了!你完全不用写循环拼接DataFrame,Polars的表达式API天生就支持批量处理多列,而且性能比循环好太多——毕竟循环会多次扫描你的Parquet文件,而批量处理只需要一次!

核心改进思路

  1. 兼容多列输入:先把fieldname参数处理成列表,不管用户传单个字符串还是列表都能统一处理
  2. 批量生成聚合表达式:在group_by后的agg步骤里,用列表推导式一次性为所有目标列生成统计逻辑
  3. 调整过滤逻辑:原来的过滤只针对单个列,现在改成检查任意一个目标列有匹配结果就保留该行
  4. 灵活排序:支持按指定列或所有统计列的总和排序

修改后的完整函数代码

def contains_html3(mindate, parquet_file = default_file, fieldname = "text"):                                            
    """ checks if html tags are in field(s) """                                                                             
    # 处理参数:兼容单个字符串或列表输入
    fieldnames = [fieldname] if isinstance(fieldname, str) else fieldname

    html_tags = [                                                                                                        
    "<html>", "</html>", "<head>", "</head>", "<title>", "</title>", "<meta>", "</meta>", "<link>", "</link>", "<style>",
    "</style>", "<body>", "</body>", "<header>", "</header>", "<footer>", "</footer>", "<nav>", "</nav>", "<main>", "</main>",       
    "<section>", "</section>", "<article>", "</article>", "<aside>", "</aside>", "<h1>", "</h1>", "<h2>", "</h2>",       
    "<h3>", "</h3>", "<h4>", "</h4>", "<h5>", "</h5>", "<h6>", "</h6>", "<p>", "</p>", "<ul>", "</ul>", "<ol>", "</ol>", 
    "<li>", "</li>", "<div>", "</div>", "<span>", "</span>", "<a>", "</a>", "<img>", "</img>", "<table>", "</table>",    
    "<thead>", "</thead>", "<tbody>", "</tbody>", "<tr>", "</tr>", "<td>", "</td>", "<th>", "</th>", "<form>", "</form>",
    "<input>", "</input>", "<textarea>", "</textarea>", "<button>", "</button>", "<select>", "</select>", "<option>", 
    "</option>", "<script>", "</script>", "<noscript>", "</noscript>", "<iframe>", "</iframe>", "<canvas>", "</canvas>", "<source>", "</source>"]

    gg = (pl.scan_parquet(parquet_file)                                                                                  
          .cast({"date": pl.Date})                                                                                       
          .select(["publisher", "date"] + fieldnames)  # 选择分组列+所有目标列                                                                      
          .drop_nulls()                                                                                                  
          .group_by("publisher", "date")                                                                                 
          # 批量生成每个列的统计表达式
          .agg([
              pl.col(col).str.contains_any(html_tags).sum().alias(col) 
              for col in fieldnames
          ])                                         
          # 过滤:只要任意一个目标列有匹配结果就保留
          .filter(pl.any_horizontal([pl.col(col) > 0 for col in fieldnames]))                                                                 
          # 可选:按所有统计列的总和降序排序,也可以指定单个列比如pl.col("text")
          .sort(pl.sum_horizontal(fieldnames).alias("total"), descending = True)
          .collect()                                                                     
         )

    return gg

关键代码说明

  • 参数兼容:fieldnames = [fieldname] if isinstance(fieldname, str) else fieldname 让函数同时支持fieldname="text"和fieldname=["text", "text1", "text2"]两种输入方式
  • 批量聚合:agg里的列表推导式会自动为每个目标列生成str.contains_any(html_tags).sum()的统计逻辑,Polars会把这些表达式合并成一个查询,一次性处理所有列
  • 过滤逻辑升级:pl.any_horizontal(...)会检查当前行的任意一个目标列是否有匹配的HTML标签,确保不会漏掉那些在其他列有匹配的行
  • 灵活排序:用pl.sum_horizontal(fieldnames)计算所有统计列的总和,按这个总和降序排序,你也可以改成pl.col("text1")来指定单个列排序

测试用例

用你提供的可复现代码生成测试数据后,直接调用:

# 生成测试数据
df = generate_df_with_tags(rows=1000, numdates=20, num_publishers=10)
# 保存为Parquet
df.write_parquet("test_data.parquet")
# 调用函数处理多列
result = contains_html3(mindate="2020-01-01", parquet_file="test_data.parquet", fieldname=["text1", "text2", "text3", "text4"])
print(result)

输出的结果会是一个包含publisher、date以及四个统计列的DataFrame,每行对应一个发布商+日期的分组,每个统计列显示该分组下对应文本列中包含HTML标签的行数。

备注:内容来源于stack exchange,提问作者Thomas Browne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:54:30