Pandas从str.extractall('#')给出错误

时间:2016-07-24 13:45:15

标签: python pandas

我正在尝试过滤推文文本中的所有#个关键字。我使用str.extractall()使用#个关键字提取所有关键字。 这是我第一次使用pandas从tweetText过滤关键字。输入,代码,预期输出和错误如下所示。

输入:

userID,tweetText 
01, home #sweet home
01, #happy #life 
02, #world peace
03, #all are one
04, world tour

依此类推......总数据文件采用GB大小的推文推文和其他几列。但我只对两个栏目感兴趣。

代码:

import re
import pandas as pd

data = pd.read_csv('Text.csv', index_col=0, header=None, names=['userID', 'tweetText'])

fout = data['tweetText'].str.extractall('#')

print fout 

预期产出:

userID,tweetText 
01,#sweet
01,#happy 
01,#life 
02,#world
03,#all

错误:

Traceback (most recent call last):
  File "keyword_split.py", line 7, in <module>
    fout = data['tweetText'].str.extractall('#')
  File "/usr/local/lib/python2.7/dist-packages/pandas/core/strings.py", line 1621, in extractall
    return str_extractall(self._orig, pat, flags=flags)
  File "/usr/local/lib/python2.7/dist-packages/pandas/core/strings.py", line 694, in str_extractall
    raise ValueError("pattern contains no capture groups")
ValueError: pattern contains no capture groups

提前感谢您的帮助。过滤关键字的最简单方法是什么?

输出更新:

仅在使用时,输出如上所述 s.name = "tweetText" data_1 = data[~data['tweetText'].isnull()]

在这种情况下,输出为空[],仍然列出的用户ID和有关键字的用户ID具有关键字数组,而不是列表形式。

仅在使用时输出我们所需的内容,但NAN

s.name = "tweetText"
data_2 = data_1.drop('tweetText', axis=1).join(s)

此处的输出格式正确,但尚未考虑没有关键字且具有NAN

如果有可能我们忽略了这样的用户ID并且根本没有显示在输出中。在接下来的阶段,我试图计算NAN或空[]也将关键字的频率被计算,该频率可能会影响远期未来的分类。

enter image description here

4 个答案:

答案 0 :(得分:7)

在微积分中设置大括号:

if(room.fail()) {       
    cout << "the room is occupied";
}
else {
    cout << "the room is free";
}

而不是

fout = data['tweetText'].str.extractall('(#)')

希望能够发挥作用

答案 1 :(得分:4)

如果您不太习惯使用extractall,可以尝试以下操作来获得最终输出:

from io import StringIO
import pandas as pd
import re


data_text = """userID,tweetText
01, home #sweet home
01, #happy #life 
02, #world peace
03, #all are one
"""

data = pd.read_csv(StringIO(data_text),header=0)

data['tweetText'] = data.tweetText.apply(lambda x: re.findall('#(?=\w+)\w+',x))
s = data.apply(lambda x: pd.Series(x['tweetText']),axis=1).stack().reset_index(level=1, drop=True)
s.name = "tweetText"
data = data.drop('tweetText', axis=1).join(s)

     userID tweetText
0       1    #sweet
1       1    #happy
1       1     #life
2       2    #world
3       3      #all
4       4       NaN

通过执行以下操作,删除textTweet列返回Nan的行:

data = data[~data['tweetText'].isnull()]

这应该返回:

   userID tweetText
0       1    #sweet
1       1    #happy
1       1     #life
2       2    #world
3       3      #all

我希望这会有所帮助。

答案 2 :(得分:3)

extractall函数需要带有捕获组的正则​​表达式作为第一个参数,并为其提供了#

可能的论点可能是(#\S+)。大括号表示捕获组,换句话说,extractall函数需要从每个字符串中提取。

示例:

data="""01, home #sweet home
01, #happy #life 
02, #world peace
03, #all are one
"""

import pandas as pd
from io import StringIO

df = pd.read_csv(StringIO(data), 
                 header=None, 
                 names=['col1', 'col2'],
                 index_col=0)

df['col2'].str.extractall('(#\S+)')

错误ValueError: pattern contains no capture groups不再出现上述代码(意味着问题中的问题已解决),但这会在当前版本的大熊猫中遇到错误(我使用过'0.18.1')。

返回的错误是:

AssertionError: 1 columns passed, passed data had 6 columns

问题描述为here

如果您尝试df['col2'].str.extractall('#(\S)')(它会为您提供每个主题标签的第一个字母),只要捕获的组只包含一个字符,您就会看到extractall函数有效(与问题描述相符)。由于问题已经结束,应该在即将发布的熊猫版本中修复。

答案 3 :(得分:0)

试试这个:

由于它过滤了&#39;#&#39;,因此您的NAN不应该存在。

    data = pd.read_csv(StringIO(data_text),header=0, index_col=0 )
    data = data["tweetText"].str.split(' ', expand=True).stack().reset_index().rename(columns = {0:"tweetText"}).drop('level_1', 1)
    data = data[data['tweetText'].str[0] == "#"].reset_index(drop=True) 


     userID tweetText
0       1    #sweet
1       1    #happy
2       1     #life
3       2    #world
4       3      #all

@Abdou方法:

def try1():
     data = pd.read_csv(StringIO(data_text),header=0)
     data['tweetText'] = data.tweetText.apply(lambda x: re.findall('#(?=\w+)\w+',x))
     s = data.apply(lambda x: pd.Series(x['tweetText']),axis=1).stack().reset_index(level=1, drop=True)
     s.name = "tweetText"
     data = data.drop('tweetText', axis=1).join(s)
     data = data[~data['tweetText'].isnull()]

%timeit try1()
 100 loops, best of 3: 7.71 ms per loop

@Merlin方法

def try2():
    data = pd.read_csv(StringIO(data_text),header=0, index_col=0 )
    data = data["tweetText"].str.split(' ', expand=True).stack().reset_index().rename(columns = {'level_0':'userID',0:"tweetText"}).drop('level_1', 1)
    data = data[data['tweetText'].str[0] == "#"].reset_index(drop=True)

%timeit try2()
100 loops, best of 3: 5.36 ms per loop