根据字符串中的单词从 DataFrame 中删除行

Removing rows from a DataFrame based on words in a string

新手程序员在此求助。 我有一个看起来像这样的数据框:

           Current
0  "Invest in $APPL, $FB and $AMZN"      
1  "Long $AAPL, Short $AMZN"              
2  "$AAPL earnings announcement soon"             
3  "$FB is releasing a new product. Will $FB's product be good?"
4  "$Fb doing good today"
5  "$AMZN high today. Will $amzn continue like this?"

我还有一个包含所有主题标签的列表:cashtags = ["$AAPL", "$FB", $AMZN"]

基本上,我想遍历 DataFrame 这一列中的所有行,并保留具有唯一现金标签的行,无论它是否大写,并删除所有其他行。 期望的输出:

           Desired
2  "$AAPL earnings announcement soon"             
3  "$FB is releasing a new product. Will $FB's product be good?"
4  "$Fb doing good today"
5  "$AMZN high today. Will $amzn continue like this?"

我基本上尝试计算该词在字符串中出现的次数,并将该值添加到新列中,以便我可以根据数字删除行。

for i in range(0,len(df)-1):
    print(i, end = "\r")
    tweet = df["Current"][i]
    count = 0
    for word in cashtags:
        count += str(tweet).count(word)
    df["Word_count"][i] = count

但是,如果我这样做,我将删除我不想删除的行。例如,多次提及唯一现金标签的行 ([3],[5])

我怎样才能达到我想要的输出?

您不应将每个现金标签的计数相加,而应将其存在或不存在相加,因为您不关心每个现金标签出现了多少次,只关心有多少现金标签。

for tag in cashtags:
    count += tag in tweet

或更简洁:sum(tag in tweet for tag in cashtags)

要使比较不区分大小写,您可以预先将推文大写。此外,在临时系列上进行过滤并避免显式循环数据帧会更加惯用(尽管您可能需要阅读更多关于 Pandas 的内容以了解其工作原理):

df[df.Current.apply(lambda tweet: sum(tag in tweet.upper() for tag in cashtags)) == 1]

如果您想将您的问题概括为任何标签,那么这是使用正则表达式的好地方。 你想匹配 ($w+)(?!.*/1) 参见例如here进行了详细的解释,但是大体结构是:

  • $w+:找到一个美元符号后跟一个或多个 letters/numbers(或 _), 如果你只是想计算你有多少个标签,这就是你所需要的

例如

df.Current.str.count(r'$\w+')

将打印

0    3
1    2
2    1
3    2
4    1
5    2

但这将消除您多次拥有相同元素的情况,因此您需要添加一个否定的前瞻性意思是不匹配

  • (?!.*/1):是一个否定的前瞻,这意味着如果后面有相同的匹配,不要匹配。这意味着只有最后一个标签被计算在字符串中。

使用它,您可以使用 pandas DataFrame.str 方法,特别是 DataFrame.str.countre.I 进行不区分大小写的匹配)

import re
df[df.Current.str.count(r'($\w+)(?!.*)', re.I) == 1]

这将为您提供所需的输出

                                             Current
2                   $AAPL earnings announcement soon
3  $FB is releasing a new product. Will $FB's pro...
4                               $Fb doing good today
5   $AMZN high today. Will $amzn continue like this?