删除停用词-Python

时间:2018-10-23 03:30:58

标签: python python-3.x

所以我正在读取一个csv文件,然后获取文件中的所有单词。然后,我尝试使用nltk删除所有停用词。我对Python很陌生,所以如果这是一个不好的问题,请原谅。 这是我的代码

    import pandas as pd
    from nltk.corpus import stopwords

def loadCsv(fileName):
    df = pd.read_csv(fileName, error_bad_lines=False)
    df.dropna(inplace = True)
    return df

def getWords(dataframe):
    words = []
    for tweet in dataframe['SentimentText'].tolist():
        for word in tweet.split():
            word = word.lower()

        words.append(word)

    return set(words) #Create a set from the words list

def removeStopWords(words):
    filtered_word_list = words[:] #make a copy of the word_list
    for word in words: # iterate over word_list
        if word in stopwords.words('english'): 
            filtered_word_list.remove(word) # remove word from filtered_word_list if it is a stopword

    return set(filtered_word_list)

df = loadCsv("train.csv")
words = getWords(df)
words = removeStopWords(words)

我收到以下错误。

  

“设置”对象不可下标

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

您将words[:]设置为一个集合,因此它不是列表,并且return list(set(words))是无意义的。

请尝试Array.sort(callback)

答案 1 :(得分:1)

您不需要在用户定义的函数中构造所有代码,我不确定是否有其背后的原因,但是问题非常简单,阅读后实际上可以用两行代码简洁地解决您的datafrme。

import pandas as pd
from nltk.corpus import stopwords

创建stop_words列表

stop_words = stopwords.words('english')
stop_words[:10]

输出

['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're"]

我将使用约翰·济慈(John Keats)的一首诗作示范,这是一个.txt文件,我将其读入数据帧。

df = pd.read_table('keats.txt', error_bad_lines = False, header = -1 , names = ['poem'], na_filter= True)
df

![enter image description here

在df中添加一个新列,称为 cleaned ,其中每一行都是小写字母并按空格分割
这实际上是您处理的第一步
您可以使用其中一个
1)lambda运算符

df['cleaned'] = list(map(lambda x: x.lower().split(), df.poem))

2)listcomp

df['cleaned'] = [x.lower().split() for x in df.poem]

enter image description here

第二步也是最后一步是过滤停用词,最简单的方法是将地图与过滤器结合使用。
将此作为第三列添加到df中:

df['filtered'] = list(map(lambda line: list(filter(lambda word: word not in stop_words, line)), df.cleaned))
df

enter image description here

如此有效,正如我之前提到的,您只需要两行代码即可处理您的数据框。



在这最后一步中还有一些要解压的东西,让我们在df.cleaned列中的第一行

df.cleaned[0]

输出

['deep', 'in', 'the', 'shady', 'sadness', 'of', 'a', 'vale']

map(filter(lambda x: according to condition, data_source))所做的是过滤不在停用词中的词

list(filter(lambda word: word not in stop_words, df.cleaned[0]))

输出

['deep', 'shady', 'sadness', 'vale']

此过滤器语句充当可传递给map(function, column)的函数 其中过滤器是函数参数,列是列df.cleaned
这样,过滤(系统)(如果要进行迭代)将应用于每行,结果将发布在新列中。 如果仔细观察,您会发现map / filter语句的框架如下:

map(lambda: line ,filter(lambda word:not in stop_words, line ),source_of_ line

请注意如何从数据帧的每一行中提取行,然后将其传递到过滤表达式中,在该表达式中对该行中的单词进行过滤。

希望我已经很好地阐明了这一点。 。

由于您是python的新手,请允许我分享一些想法 1- python是一种简洁的语言,旨在简洁和易读。一个人可以做的最愚蠢的事情是为循环显式地编写,除非循环所必需的几乎总是可以用listcomps或generator表达式替换。用户定义的功能也是如此。

2-有很多它是从2.7继承的代码,例如words[:],您不再需要[:]位。

3-尝试了解容器的属性,python中的容器是 list tuple set dict 。当您尝试对集合进行切片时,通常会返回您超出集合的错误,我指的是将子集切成一部分。如果有集合,则呼叫为set_1,而您进行set_1[:10]则得到set object not subscriptabl。这是因为集合是python中的非序列化容器,这意味着集合的元素没有分配索引,因此您无法像对列表那样对集合进行排序或子集化或调用第一个,第二个或第N个元素。可以使用dir(object)

显示实例方法和对象的属性

4-永远不要停止修改代码

答案 2 :(得分:0)

函数set的返回是一个removeStopWords对象,然后将其作为参数传递给函数filtered_word_list = words[:] ,在它的第一条语句中,您尝试使用奇特的索引访问值操作:

getWords

您需要做的就是将集合强制转换为列表,然后再通过return list(set(words)) #Create a set from the words list 方法将其返回:

    [pom.xml] - add freemaker dependency
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>

    [Controller]
    @CrossOrigin
    @SkipSessionCheck
    @GetMapping(baseUri+"/buy/pg/test")
    public ModelAndView impViewTest() throws ResultCodeException {
        try {

            System.out.println("/buy/pg/test") ;
            logger.debug("/buy/pg/test") ;
            ModelAndView model = new ModelAndView();

            model.addObject("errorTitle", "Error") ;
            model.addObject("errorMessage", "success : No Error !!!") ;
            model.setViewName("paygate/error");
            return model ;
        }
        catch(Exception e){
            logger.error(AppUtil.excetionToString(e)) ;
            ModelAndView model = new ModelAndView();

            model.addObject("errorTitle", "Error") ;
            model.addObject("errorMessage", e.getMessage()) ;
            model.setViewName("paygate/error");
            return model ;
        }
    }

    [error.ftl] - view file extension is ftl
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>error</title>
     </head>
    <body>
    <h1>${errorTitle}</h1>
    <p>${errorMessage}</p>

    </body>
    </html>

答案 3 :(得分:0)

filtered_word_list = words[:] #make a copy of the word_list

这里words是一个集合,而不是列表,因此此行将引发错误。您可以使用列表推导来创建不停词列表:

return [x for x in words if x not in stopwords.words('english')]

这避免了复制,也不需要words作为列表。