根据字符串中的单词从 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.count
(re.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?
新手程序员在此求助。 我有一个看起来像这样的数据框:
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.count
(re.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?