此处的新手程序员正在寻求帮助。 我有一个看起来像这样的数据框:
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])
如何获得所需的输出?
答案 0 :(得分:3)
您应该对每个现金标签的存在或不存在进行汇总,而不是对每个现金标签的计数求和,因为您不必在乎每个现金标签出现多少次,而只在乎多少现金标签。
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]
答案 1 :(得分:1)
如果您想将问题推广到任何标签,那么这是使用正则表达式的好地方。
您想与(\$w+)(?!.*/1)
进行比对,例如here进行了详细说明,但是一般结构为:
\$w+
:找到一个美元符号,后跟一个或多个字母/数字(或
_
),如果您只想计算您拥有多少标签,这就是您所需要的例如
df.Current.str.count(r'\$\w+')
将打印
0 3
1 2
2 1
3 2
4 1
5 2
但是这将删除多个元素具有相同元素的情况,因此您需要添加负向提前表示不匹配
(?!.*/1)
:前瞻性为负,表示不匹配,如果稍后再进行相同的匹配。这将意味着在字符串中仅计算最后一个标签。使用此方法,您可以使用熊猫DataFrame.str
方法,特别是DataFrame.str.count
(re.I
区分大小写)
import re
df[df.Current.str.count(r'(\$\w+)(?!.*\1)', 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?