【问题标题】:Pandas: delete cells if last six characters contain any integer below thresholdPandas:如果最后六个字符包含低于阈值的任何整数,则删除单元格
【发布时间】:2018-10-12 00:50:42
【问题描述】:

请原谅我的标题;我很难总结一个复杂的问题。

我有一个看起来像这样的值的 pandas 数据框:

    col1         col2            col3          col4       
10_Q999999   111_Q4987666    110_Q277778   111_Q999999

假设阈值为 7。我需要获取该数据帧并删除 _Q 之后的任何数字低于阈值 7 的每个单元格。对于每个数字 >= 7 的单元格,我只想保留该部分“_Q”之前的字符串。

所需的输出如下所示:

  col1            col2            col3          col4       
   10                                           111

我正在想办法用“_Q”分割每一列,将最后一段转换为整数列表,取最小值,然后将最小值与阈值进行比较,最后删除整数列表,但我被困在令人作呕的嵌套列表理解中:

[[[int(z) for z in y[-3:] if (z != '') and "Q" not in z ] for y in chunk[x].astype(str).str.split("_") if y != ''] for x in chunk[cols] if x != '']

解决方法:

s=~chunk.apply(lambda x : 
x.str.split('_Q').str[1].str.contains('[0:6]', na=False))
        chunk = chunk.apply(lambda x : x.str.split('_Q').str[0])[s].fillna('')

【问题讨论】:

    标签: python-3.x list pandas dataframe filter


    【解决方案1】:

    您可以将splitcontains 一起使用

    s=~df.apply(lambda x : x.str.split('_Q').str[1].str.contains('1|2|3|4|5|6'))
    df.apply(lambda x : x.str.split('_Q').str[0])[s].fillna('')
    Out[549]: 
      col1 col2 col3 col4
    0   10            111
    

    【讨论】:

    • @SummerEla 误会,请查看更新
    • 你刚刚拯救了我的一天。非常感谢!
    • 我确实需要添加一个参数来处理 na:na=False。这位女士非常感谢您的帮助:)
    • 您可以将1|2|3|... 替换为[0-6]
    • 从 1 开始切换 | 2 | 3| @COLDSPEED 建议的 [0-x] 等确实提高了速度。由于阈值是用户输入值,我每次都必须执行 '|".join 来创建字符串,而这只是使用字符串格式输入阈值。非常感谢!
    【解决方案2】:

    我不喜欢apply,因此我概述了一个涉及stackstr.splitnp.where 的替代方案,以便(希望)获得更好的性能。

    v = df.stack()
    sp = v.str.split('_Q')
    i, j = sp.str[0], sp.str[1]
    
    v[:] = np.where(j.str.contains('[0-6]'), '', i)
    v.unstack()
    
      col1 col2 col3 col4
    0   10            111
    

    【讨论】:

    • 感谢您的建议。可悲的是,我表明这比 Wen 的方法要慢一些。应用:real 0m1.289s user 0m1.417s sys 0m3.403s stack:real 0m1.401s user 0m1.550s sys 0m3.524s
    • @SummerEla 好的,谢谢。我认为问题出在堆栈上,这几乎和应用一样慢。我希望他们修复它;有很大的改进空间;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    相关资源
    最近更新 更多