【问题标题】:Drop rows from Pandas data frame by matching a substring list通过匹配子字符串列表从 Pandas 数据框中删除行
【发布时间】:2017-02-25 12:35:06
【问题描述】:

我有一个字符串列表如下:

drop_list = [ "www.stackoverflow", "www.youtube."]

我有一个 Pandas 数据框 df 有一个列,比如名称 column_name1,它可能包含也可能不包含 drop_list 中的子字符串。示例df如下:

columnname1
------------
https://stackoverflow.com/python-pandas-drop-rows-string-match-from-list
https://stackoverflow.com/deleting-dataframe-row-in-pandas-column-value
https://textblob.readthedocs.io/en/dev/quickstart.html#create-a-textblob
https://textblob.readthedocs.io/en/dev/
https://textblob.readthedocs.io/en/stackoverflow
https://textblob.readthedocs.io/en/youtube
https://www.youtube.com/watch?v=sHkjdkjsk
https://www.youtube.com/watch?v=_jksjdkjklI
https://www.youtube.com/watch?v=jkjskjkjkjkw

所以,我想从 df 中删除所有行,其中包含来自drop_list 的子字符串。

如果我理解正确,如果 drop_list 是我想要匹配的确切值,我可以根据这个SO 问题使用以下代码。

df[~df['column_name1'].isin(to_drop)]

或使用str.contains 答案中建议的str.contains 方法,如果它只是一个值

df[~df['column_name1'].str.contains("XYZ")]

现在,如何结合这两种方法来删除列?所需的输出是删除任何包含 stackoverflowyoutube 的行来自我的数据框:

columnname1
------------
https://textblob.readthedocs.io/en/dev/quickstart.html#create-a-textblob
https://textblob.readthedocs.io/en/dev/
https://textblob.readthedocs.io/en/stackoverflow
https://textblob.readthedocs.io/en/youtube

如果我使用 to_drop 原样运行 df = df[~df['col1'].str.contains('|'.join(to_drop))],它会保留 stackoverflow 网址,但会删除 youtube 网址。

如果我将列表更改为更通用,如下所示 to_drop = ["stackoverflow", "youtube"]

删除

https://textblob.readthedocs.io/en/stackoverflow
https://textblob.readthedocs.io/en/youtube

所以,我要做的就是删除所有包含 stackoverflow 和 youtube url 的行。我正在避免使用 urlparse 库!

Here 是 MWE。

【问题讨论】:

  • 请提供样本数据集和所需数据集
  • .str.contains('|'.join(to_drop)) 可用于检查to_drop 中的所有元素,但我不确定这是否是您要问的。在我看来,样品也很好。
  • 添加了示例数据集。 .str.contains('|'.join(to_drop)) 我相信不会解决。
  • @kingmakerking,你为什么相信.str.contains('|'.join(to_drop)) - 不会解决问题?
  • @MaxU 因为它会尝试匹配 www.stackoverflow | www.youtube. 作为一个完整的模式,因为 '|'.join()?我以前用过,但对于这种情况,至少在我的 df 中,它保留了许多包含 stackoverflow 或 youtube 的行。

标签: python string pandas dataframe pattern-matching


【解决方案1】:

试试这个:

import re

drp = [re.sub(r'www\.|\.$|\.com', '', x) for x in to_drop]
df[~df.col1.str.extract(r'http[s]*://([^/]*).*', expand=False)
  .str.contains('|'.join(drp))]

产量:

                                                                       col1
2  https://textblob.readthedocs.io/en/dev/quickstart.html#create-a-textblob
3                                   https://textblob.readthedocs.io/en/dev/
4                          https://textblob.readthedocs.io/en/stackoverflow
5                                https://textblob.readthedocs.io/en/youtube

解释:

In [38]: drp
Out[38]: ['stackoverflow', 'youtube']

In [41]: df.col1.str.extract(r'http[s]*://([^/]*).*', expand=False)
Out[41]:
0          stackoverflow.com
1          stackoverflow.com
2    textblob.readthedocs.io
3    textblob.readthedocs.io
4    textblob.readthedocs.io
5    textblob.readthedocs.io
6            www.youtube.com
7            www.youtube.com
8            www.youtube.com
Name: col1, dtype: object

In [42]: df.col1.str.extract(r'http[s]*://([^/]*).*', expand=False).str.contains('|'.join(drp))
Out[42]:
0     True
1     True
2    False
3    False
4    False
5    False
6     True
7     True
8     True
Name: col1, dtype: bool

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 2020-08-12
    • 2016-03-21
    • 2020-02-10
    • 2021-01-18
    相关资源
    最近更新 更多