【问题标题】:Search for "does-not-contain" on a DataFrame in pandas在 pandas 的 DataFrame 上搜索“不包含”
【发布时间】:2013-06-10 11:06:27
【问题描述】:

我已经进行了一些搜索,但无法弄清楚如何通过df["col"].str.contains(word) 过滤数据帧,但是我想知道是否有相反的方法:通过该集合的恭维过滤数据帧。例如:大意为!(df["col"].str.contains(word))

这可以通过DataFrame 方法完成吗?

【问题讨论】:

    标签: python pandas contains


    【解决方案1】:

    您可以使用反转 (~) 运算符(其作用类似于布尔数据的 not):

    new_df = df[~df["col"].str.contains(word)]
    

    ,其中new_df 是 RHS 返回的副本。

    包含也接受正则表达式...


    如果上面抛出ValueError,原因很可能是你的数据类型混合,所以使用na=False

    new_df = df[~df["col"].str.contains(word, na=False)]
    

    或者,

    new_df = df[df["col"].str.contains(word) == False]
    

    【讨论】:

    • 完美!我对 regex 很熟悉,并认为它在 Python 中有所不同 - 看到了很多关于 re.complies 的文章,并告诉自己我稍后会谈到。看起来我过度拟合了搜索,就像你说的那样:)
    • 也许一个完整的例子会有所帮助:df[~df.col.str.contains(word)] 返回原始数据帧的副本,其中包含与单词匹配的排除行。
    【解决方案2】:

    在使用上面 Andy 推荐的命令之前,我必须去掉 NULL 值。一个例子:

    df = pd.DataFrame(index = [0, 1, 2], columns=['first', 'second', 'third'])
    df.ix[:, 'first'] = 'myword'
    df.ix[0, 'second'] = 'myword'
    df.ix[2, 'second'] = 'myword'
    df.ix[1, 'third'] = 'myword'
    df
    
        first   second  third
    0   myword  myword   NaN
    1   myword  NaN      myword 
    2   myword  myword   NaN
    

    现在运行命令:

    ~df["second"].str.contains(word)
    

    我收到以下错误:

    TypeError: bad operand type for unary ~: 'float'
    

    我首先使用 dropna() 或 fillna() 删除了 NULL 值,然后重试该命令没有问题。

    【讨论】:

    • 也可以使用~df["second"].astype(str).str.contains(word)强制转换为str。见stackoverflow.com/questions/43568760/…
    • @Shoresh 我们也可以使用 na = False 作为这个问题的解决方案
    【解决方案3】:

    我也遇到了非 (~) 符号的问题,所以这是另一个 StackOverflow thread 的另一种方法:

    df[df["col"].str.contains('this|that')==False]
    

    【讨论】:

    • 可以这样组合吗? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]?谢谢!
    • 是的,你可以。语法在这里解释:stackoverflow.com/questions/22086116/…
    • 不要忘记,如果我们想要 rwmove 包含“|”的行我们应该使用“\”,例如df = df[~df["col"].str.contains('\|')]
    【解决方案4】:

    除了 nanselm2 的回答,您可以使用 0 代替 False

    df["col"].str.contains(word)==0
    

    【讨论】:

    • 看起来这也删除了NaN的所有行
    【解决方案5】:

    您可以使用 Apply 和 Lambda:

    df[df["col"].apply(lambda x: word not in x)]
    

    或者如果你想定义更复杂的规则,你可以使用AND:

    df[df["col"].apply(lambda x: word_1 not in x and word_2 not in x)]
    

    【讨论】:

    • 它不适用于 contains 但适用于 equals。
    • 我修好了,现在应该没问题了@RamanJoshi
    • 我认为 'in' 用于检查等于,所以 'not in' 将检查不等于,不会检查不包含。对吗?
    • @RamanJoshi 请阅读问题:搜索“does-not-contain”
    • 我已经仔细阅读了这个问题,这就是为什么我要对你说“不等于”和“不包含”之间有很大的区别。例如。如果我们有包含项目 ["hello", "world", "test"] 的列表,并且如果我们想检查 "not equals" 那么文本 "ello" 将返回 "true",因为文本不等于任何项目。但是当我们检查“not contains”时,它应该将“false”作为一项返回,即“Hello”包含文本“ello”。我认为你的问题是错误的。
    【解决方案6】:

    我希望答案已经发布了

    我正在添加框架来查找多个单词并从 dataFrame 中取反

    这里'word1','word2','word3','word4' = 要搜索的模式列表

    df = 数据帧

    column_a = 来自 DataFrame df 的列名

    values_to_remove = ['word1','word2','word3','word4'] 
    
    pattern = '|'.join(values_to_remove)
    
    result = df.loc[~df['column_a'].str.contains(pattern, case=False)]
    

    【讨论】:

    • 这是唯一对我有用的方法
    【解决方案7】:

    为了补充上述问题,如果有人想删除所有带有字符串的行,可以这样做: df_new=df[~df['col_name'].apply(lambda x: isinstance(x, str))]

    【讨论】:

      猜你喜欢
      • 2020-09-15
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 2018-03-19
      • 2021-07-25
      • 1970-01-01
      相关资源
      最近更新 更多