Python' str.contains'函数没有返回正确的值

时间:2018-01-19 07:36:16

标签: python pandas dataframe

我正在尝试使用' pandas'对数据框进行子集化。如果列匹配特定模式。以下是可重复的示例供参考。

import pandas as pd

# Create Dataframe having 10 rows and 2 columns 'code' and 'URL'
df = pd.DataFrame({'code': [1,1,2,2,3,4,1,2,2,5],
                   'URL': ['www.abc.de','https://www.abc.fr/-de','www.abc.fr','www.abc.fr','www.abc.co.uk','www.abc.es','www.abc.de','www.abc.fr','www.abc.fr','www.abc.it']})

# Create new dataframe by filtering out all rows where the column 'code' is equal to 1
new_df = df[df['code'] == 1]

# Below is how the new dataframe looks like
print(new_df)
                      URL  code
0              www.abc.de     1
1  https://www.abc.fr/-de     1
6              www.abc.de     1

以下是dtypes供参考。

print(new_df.dtypes)
URL     object
code     int64
dtype: object

# Now I am trying to exclude all those rows where the 'URL' column does not have .de as the pattern. This should retain only the 2nd row in new_df from above output
new_df = new_df[~ new_df['URL'].str.contains(r".de", case = True)]

# Below is how the output looks like
print(new_df)
Empty DataFrame
Columns: [URL, code]
Index: []

以下是我的问题。 1)为什么'URL'列首先出现,即使我先定义'code'列?

2)当我尝试删除“' URL'的所有行时,我的代码出了什么问题?列没有模式.de?在R中,我只需使用下面的代码就可以轻松获得所需的结果。

new_df <- new_df[grep(".de",new_df$URL, fixed = TRUE, invert = TRUE), ]

所需的输出应如下所示。

# Desired output for new_df
                   URL  code
https://www.abc.fr/-de     1

对此的任何指导都将非常感激。

1 个答案:

答案 0 :(得分:3)

  

为什么“URL”列首先出现,即使我定义了   '代码'列首先?

这是因为没有订购字典这一事实。根据python解释器的随机哈希初始化,读入和按任何顺序创建列。

  

当我尝试删除所有这些行时,我的代码出了什么问题   “URL”列没有模式.de?

你需要逃避.,因为这是一个特殊的正则表达式元字符。

df[df.code.eq(1) & ~df.URL.str.contains(r'\.de$', case=True)]

                      URL  code
1  https://www.abc.fr/-de     1

如果在TLD之后的任何地方(而不是最后)可以找到de,这可能不会令人难以接受。这是解决该限制的一般解决方案 -

p = '''.*       # match anything, greedily  
       \.       # literal dot
       de       # "de"
       (?!.*    # negative lookahead
       \.       # literal dot (should not be found)
       )'''
df[df.code.eq(1) & ~df.URL.str.contains(p, case=True, flags=re.VERBOSE)]

                      URL  code
1  https://www.abc.fr/-de     1