如何忽略可变尾部空格 按后缀筛选排序pandas DataFrame
问题原因
直接调用字符串的endswith('_d')方法时,会严格校验字符串最后两位是否为_d,如果后缀后带有数量不等的尾部空格,字符串末尾实际是空格字符,自然无法命中匹配规则,导致带空格的条目被漏判。
实现方案
核心思路有两种:要么先清除字符串尾部的所有空白字符再做后缀匹配,要么用正则规则兼容后缀后跟随任意数量空格的场景,两种方案都不会修改原始存储的字符串内容。
方案1:清洗尾部空格后匹配(逻辑最直观)
用pandas字符串接口的rstrip()方法清除所有尾部空白(包含空格、制表符等),再做后缀判断即可,同时避免使用逐行iloc循环的低效写法,直接用pandas向量化操作完成分组筛选:
import pandas as pd obs_d = [ "48973a_d ", "48973a_h ", "48973adt ", "art_223wtb_d", "art_223wtb_h", "art_223wtbdt"] values = [ 1.3664, 1.02E-02, 191.84, 1.39E-04, 1.53E-02, 14.267] d = {'obs': obs_d, 'vals': values} df = pd.DataFrame(data=d) # 生成仅去除尾部空白的临时列,不修改原始obs值 df['obs_stripped'] = df['obs'].str.rstrip() # 按后缀筛选生成对应字典 ddns = dict(zip( df[df['obs_stripped'].str.endswith('_d')]['obs'], df[df['obs_stripped'].str.endswith('_d')]['vals'] )) hds = dict(zip( df[df['obs_stripped'].str.endswith('_h')]['obs'], df[df['obs_stripped'].str.endswith('_h')]['vals'] )) dt = dict(zip( df[df['obs_stripped'].str.endswith('dt')]['obs'], df[df['obs_stripped'].str.endswith('dt')]['vals'] ))
运行后ddns会同时捕获"48973a_d "和"art_223wtb_d"两个条目,不会出现漏判。
方案2:正则直接匹配(无需生成临时列)
如果不想额外生成清洗列,可以直接用正则规则匹配「目标后缀 + 任意数量空白(含0个) + 字符串结尾」的模式,一步完成筛选:
# 正则规则说明:\s*$ 表示匹配0到多个空白字符直到字符串末尾 ddns = dict(zip( df[df['obs'].str.contains(r'_d\s*$')]['obs'], df[df['obs'].str.contains(r'_d\s*$')]['vals'] )) hds = dict(zip( df[df['obs'].str.contains(r'_h\s*$')]['obs'], df[df['obs'].str.contains(r'_h\s*$')]['vals'] )) dt = dict(zip( df[df['obs'].str.contains(r'dt\s*$')]['obs'], df[df['obs'].str.contains(r'dt\s*$')]['vals'] ))
注意:正则字符串前要加
r标记为原始字符串,避免转义字符导致匹配失效。
性能提示
逐行遍历df.iloc的写法在数据量超过千行时性能会远低于pandas内置的向量化字符串操作,非必要不要使用循环逐行处理DataFrame。
内容的提问来源于stack exchange,提问作者emma_kth
相关产品推荐
相关产品推荐

