【问题标题】:Pandas multiple find strings熊猫多个查找字符串
【发布时间】:2018-11-23 05:22:09
【问题描述】:

我正在编写一个脚本来读取和处理 Excel 文件中的数据,我需要过滤包含多个字符串的行。

目前,我正在阅读的每种类型的 Excel 工作表(每种工作表类型都有一个从处理读取文件和第一次处理的父级继承的子类)的过滤器方法是硬编码的,但是这样得到随着我要分析的工作表数量不断增加,这非常乏味,我正在寻找更优雅的解决方案。

现在,我是这样实现的:

def _find(self,find_str,column='Data1'):
    return (self.df[column].str.find(find_str) > -1)
def filter(self):
    self.df_filter = self.df[(self._find('This') | self._find('is')) 
                           & self._find('an') | self._find('example')]

为每个子类重新实现过滤器方法。有时,逻辑(实际上是二进制)表达式会变得很长。

是否有一种一致的、可读的方式来缩短它? 我想到了将类似逻辑表达式的对象传递给通用过滤器函数的方法,例如

gen_find(('This' | 'is') & 'an' | 'example')

(我知道这可能是个坏主意,但你明白了)

【问题讨论】:

    标签: python string python-3.x pandas series


    【解决方案1】:

    pd.Series.str.find(x) > -1 等价于pd.Series.str.contains(x)。两者都提供布尔系列,您可以使用它来过滤您的数据框。简化逻辑的一种方法是将正则表达式与pd.Series.str.contains 结合使用。

    例如,定义一个您希望查找的子字符串列表:

    L = ['This', 'is', 'an', 'example']
    

    然后将它们组合成一个正则表达式。如果您有需要转义的字符,请使用re.escape

    import re
    regexp = '|'.join([re.escape(i) for i in L])
    

    最后,将此表达式合并到您的系列掩码中:

    df = df[df['col'].str.contains(regexp)]
    

    您可以使用& 运算符组合多个or 条件:

    mask1 = df['col'].str.contains(regexp1)
    mask2 = df['col'].str.contains(regexp2)
    
    df = df[mask1 & mask2]
    

    【讨论】:

    • 谢谢,这在一定程度上缩短了我的代码,但并没有真正摆脱在每个子类中定义过滤器方法的需要。
    • 当然,希望有人有更好的解决方案。保持这个问题开放。也许有 or_conditions 正则表达式方法的智能交集。
    猜你喜欢
    • 1970-01-01
    • 2015-01-26
    • 2023-01-11
    • 2019-07-24
    • 2018-01-28
    • 2021-09-21
    • 2021-10-12
    • 2018-10-31
    • 2021-12-14
    相关资源
    最近更新 更多