我有一个像这样的csv文件
text
RT @CritCareMed: New Article: Male-Predominant Plasma Transfusion Strategy for Preventing Transfusion-Related Acute Lung Injury... htp://…
#CRISPR Inversion of CTCF Sites Alters Genome Topology & Enhancer/Promoter Function in @CellCellPress htp://.co/HrjDwbm7NN
RT @gvwilson: Where's the theory for software engineering? Behind a paywall, that's where. htp://.co/1t3TymiF3M #semat #fail
RT @sciencemagazine: What’s killing off the sea stars? htp://.co/J19FnigwM9 #ecology
RT @MHendr1cks: Eve Marder describes a horror that is familiar to worm connectome gazers. htp://.co/AEqc7NOWoR via @nucAmbiguous htp://…
我想从推文文本中提取所有提及(以'@'开头)。到目前为止,我已经完成了这个
import pandas as pd
import re
mydata = pd.read_csv("C:/Users/file.csv")
X = mydata.ix[:,:]
X=X.iloc[:,:1] #I have multiple columns so I'm selecting the first column only that is 'text'
for i in range(X.shape[0]):
result = re.findall("(^|[^@\w])@(\w{1,25})", str(X.iloc[:i,:]))
print(result);
这里有两个问题:
第一:在str(X.iloc[:1,:])
它给了我['CritCareMed']
这不正确,因为它应该给我['CellCellPress']
,在str(X.iloc[:2,:])
它再次给我['CritCareMed']
这是当然不好了。我得到的最终结果是
[('','CritCareMed'),('','gvwilson'),('','sciencemagazine')]
它不包括第二行中的提及以及最后一行中的两个提及。 我想要的应该是这样的:
如何实现这些结果?这只是一个示例数据,我的原始数据有很多推文,方法还可以吗?
答案 0 :(得分:1)
您可以使用str.findall
方法来避免for循环,使用负面隐藏替换(^|[^@\w])
,这会形成您在正则表达式中不需要的另一个捕获组:
df['mention'] = df.text.str.findall(r'(?<![@\w])@(\w{1,25})').apply(','.join)
df
# text mention
#0 RT @CritCareMed: New Article: Male-Predominant... CritCareMed
#1 #CRISPR Inversion of CTCF Sites Alters Genome ... CellCellPress
#2 RT @gvwilson: Where's the theory for software ... gvwilson
#3 RT @sciencemagazine: What’s killing off the se... sciencemagazine
#4 RT @MHendr1cks: Eve Marder describes a horror ... MHendr1cks,nucAmbiguous
同样X.iloc[:i,:]
返回一个数据框,因此str(X.iloc[:i,:])
为您提供数据框的字符串表示形式,它与单元格中的元素非常不同,从{提取实际字符串{1}}列,您可以使用text
或更好的方式来遍历列,请使用iteritems
:
X.text.iloc[0]
答案 1 :(得分:1)
虽然您已经有了答案,但您甚至可以尝试优化整个导入过程:
import re, pandas as pd
rx = re.compile(r'@([^:\s]+)')
with open("test.txt") as fp:
dft = ([line, ",".join(rx.findall(line))] for line in fp.readlines())
df = pd.DataFrame(dft, columns = ['text', 'mention'])
print(df)
<小时/> 产量:
text mention
0 RT @CritCareMed: New Article: Male-Predominant... CritCareMed
1 #CRISPR Inversion of CTCF Sites Alters Genome ... CellCellPress
2 RT @gvwilson: Where's the theory for software ... gvwilson
3 RT @sciencemagazine: What’s killing off the se... sciencemagazine
4 RT @MHendr1cks: Eve Marder describes a horror ... MHendr1cks,nucAmbiguous
这可能会更快一些,因为您不需要在df
已经构建后更改它。
答案 2 :(得分:1)
mydata['text'].str.findall(r'(?:(?<=\s)|(?<=^))@.*?(?=\s|$)')
与此相同:Extract hashtags from columns of a pandas dataframe,但要提及。
@.*?
对单词开头进行非贪心匹配
带有标签(?=\s|$)
向前看单词的结尾或句子的结尾(?:(?<=\s)|(?<=^))
向后看以确保如果在单词中间使用@则不会出现误报后面的正则表达式断言空格或句子开头必须在@字符之前。