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

Polars字符串列高效过滤:内存优化与纯表达式实现咨询

处理大文本列的Polars性能与内存问题

问题背景

我有一列长字符串(如语句),需完成以下处理:

  • 替换特定字符;
  • 拆分剩余字符串为列表;
  • 纯文本字符串若在字典中则保留;
  • 纯数字字符串保留;
  • 混合字符串按数字与字母比率筛选。

当前实现方式:遍历目标列,使用Polars的map_elements调用Python自定义函数filter_field完成处理,该函数通过正则替换、拆分字符串、计算字符比率等逻辑实现过滤。

  • 处理128M行数据耗时约10分钟;
  • 处理300M行时内存持续增长直至被Ubuntu系统终止,且仅单核心运行。

核心问题

  1. 原方案内存增长是否正常?map_elements是否会复制原序列导致内存消耗增加?
  2. 原方案是否合理,有无更优实现方式(如使用Polars的struct)?
  3. 能否仅通过Polars表达式完成上述所有过滤逻辑?

额外问题

尝试使用Polars表达式后性能大幅提升,但存在两个问题:

  • 字典查询复杂度严重影响运行效率;
  • 使用pl.DataFrame保存为parquet格式时出现段错误,改用pl.LazyFrame+sink_parquet无错误但耗时显著增加。

示例数据

temp = pl.DataFrame({"foo": ['COOOPS.autom.SAPF124',
                            'OSS REEE PAAA comp. BEEE  atm 6079 19000000070 04-04-2023',
                            'ABCD 600000000397/7667896-6/REG.REF.REE PREPREO/HMO',
                            'OSS REFF pagopago cost. Becf  atm 9682 50012345726 10-04-2023']
                    })

自定义函数代码

def num_dec(x):
    return len(re.findall(r'[0-9_\/]', x))

def num_letter(x):
    return len(re.findall(r'[A-Za-z]', x))

def letter_dec_ratio(x):
    if len(x) == 0:
        return None
    nl = num_letter(x)
    nd = num_dec(x)
    if (nl + nd) == 0:       
        return None
    ratio = (nl - nd)/(nl + nd)
    return ratio

def filter_field(text=None, word_dict=None):

    if type(text) is not str or word_dict is None:
        return 'no memo and/or dictionary'

    if len(text) > 100:
        text = text[0:101]
    print("TEXT: ",text)
    text_sani = re.sub(r'[^a-zA-Z0-9\s\_\-\%]', ' ', text) # parse by replacing most artifacts and symbols with space 

    words = text_sani.split(' ') # create words separated by spaces
    print("WORDS: ",words)

    kept = []
    ratios = [letter_dec_ratio(w) for w in words]
    [kept.append(w.lower()) for i, w in enumerate(words) if ratios[i] is not None and ((ratios[i] == -1 or (-0.7 <= ratios[i] <= 0)) or (ratios[i] == 1 and w.lower() in word_dict))]
    print("FINAL: ",' '.join(kept))

    return ' '.join(kept)

当前实现代码

temp.with_columns(
                pl.col("foo").map_elements(
                    lambda x: filter_field(text=x, word_dict=['cost','atm'])).alias('clean_foo') # baseline
                )

Polars表达式部分尝试代码

temp.with_columns(
    (
        pl.col(col)
        .str.replace_all(r'[^a-zA-Z0-9\s\_\-\%]',' ')
        .str.split(' ')
    )
)

预期结果

TEXT:  COOOPS.autom.SAPF124
WORDS:  ['COOOPS', 'autom', 'SAPF124']
FINAL:  
TEXT:  OSS REEE PAAA comp. BEEE  atm 6079 19000000070 04-04-2023
WORDS:  ['OSS', 'REEE', 'PAAA', 'comp', '', 'BEEE', '', 'atm', '6079', '19000000070', '04-04-2023']
FINAL:  atm 6079 19000000070 04-04-2023
TEXT:  ABCD 600000000397/7667896-6/REG.REF.REE PREPREO/HMO
WORDS:  ['ABCD', '600000000397', '7667896-6', 'REG', 'REF', 'REE', 'PREPREO', 'HMO']
FINAL:  600000000397 7667896-6
TEXT:  OSS REFF pagopago cost. Becf  atm 9682 50012345726 10-04-2023
WORDS:  ['OSS', 'REFF', 'pagopago', 'cost', '', 'Becf', '', 'atm', '9682', '50012345726', '10-04-2023']
FINAL:  cost atm 9682 50012345726 10-04-2023

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:45