【问题标题】:I'm trying to get word frequency on tweet text from a csv file using pandas value counts我正在尝试使用熊猫值计数从 csv 文件中获取推文文本的词频
【发布时间】:2020-06-22 20:09:08
【问题描述】:

这是我的代码:

import nltk
from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer
from nltk.stem import WordNetLemmatizer
import pandas as pd
import numpy as np
import openpyxl
import string

tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()


def remove_stopwords(df_text):
    words = [w for w in df_text if w not in stopwords.words('english')]
    return words

def word_lemmatizer(df_text):
    lem_text = [lemmatizer.lemmatize(i) for i in df_text]
    return lem_text

#works fine from here
df = pd.read_csv('amazonfresh-test.csv', encoding='utf-8', converters={'text': str})


df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'].apply(lambda x: remove_stopwords(x))
df['text'].apply(lambda x: word_lemmatizer(x))

#to here

#this is where I have issues
data_count = df['test'].apply(pd.value_counts())

data_count.to_excel("amazonfresh-test.xlsx")

它需要很长时间才能运行,我只是尝试剥离和拆分文本列每一行中的字符串,然后让总字数显示字频。

Here is what the csv looks like:

Here is the new csv with words in their own cell, still struggling to get the value_count on this.

【问题讨论】:

  • 你能提供'amazonfresh-test.csv'的样本吗?
  • 是的,刚刚@Phillyclause89
  • @Phillyclause89 它发生在没有错字的情况下。我能够在没有太多问题的情况下进行词形还原、删除停用词和标记化。但我有一个问题只是试图获取列中文本的值计数
  • @Phillyclause89 是的,只是想计算剩余的令牌,你建议的脚本只输出数字
  • 在玩了这个之后有两个想法。 1) 请记住 pandas.Series.apply 默认不是就地方法。我认为您想在这三行中执行df['text'] = df['text'].apply(func),看起来您想要对文本列中的数据进行标记和过滤。 2)我认为您想从data_count = df['test'].apply(pd.value_counts()) 行中的pd.value_counts 函数中删除调用者。试试data_count = df['test'].apply(pd.value_counts)?

标签: python pandas dataframe series


【解决方案1】:

在与 OP 的 cmets 中反复讨论了相当多的内容后,我决定最好在这里总结一下我的建议。

第一个问题是data_count = df['test'].apply(pd.value_counts())有两个错别字。

该行实际上应该是data_count = df['text'].apply(pd.value_counts)

df['test'] 将引发 KeyError,因为 OP 的 pandas.DataFrame 中没有 'test' 列。另一个错字是对pandas.value_counts 的无参数调用到pandas.Series.apply 方法的调用者。这将引发TypeError,因为pandas.value_counts 函数至少需要一个参数。但这很容易通过删除调用者来解决,因为pandas.Series.apply 方法的目的是让它使用系列中的每个值作为参数为我们调用函数。

我注意到的下一个问题是 pandas.Series.apply 方法的其他三个调用:

df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'].apply(lambda x: remove_stopwords(x))
df['text'].apply(lambda x: word_lemmatizer(x))

这三行写得好像pandas.Series.apply 是一个就地方法,但它不是。要真正让这些更改分配给dfpandas.DataFrame 对象,需要在这里实际使用分配:

df['text'] = df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'] = df['text'].apply(remove_stopwords)
df['text'] = df['text'].apply(word_lemmatizer)

此外,只有在第一次调用时才需要 lambda 表达式来执行 x.lower() 部分,因为 remove_stopwordsword_lemmatizer 都按原样取值,我们不需要额外的 lambda。最后,所有三行代码都可以压缩为一个 pandas.Series.apply 的调用,因为将这些函数应用于相同的值:

df['text'] = df['text'].apply(
    lambda x: word_lemmatizer(
        remove_stopwords(
            tokenizer.tokenize(x.lower())
        )
    )
)

我希望 OP 能够从我的 cmets 中整合的完整代码应该如下所示:

from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer
from nltk.stem import WordNetLemmatizer
import pandas as pd

tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()


def remove_stopwords(df_text):
    words = [w for w in df_text if w not in stopwords.words('english')]
    return words


def word_lemmatizer(df_text):
    lem_text = [lemmatizer.lemmatize(i) for i in df_text]
    return lem_text


df = pd.read_csv('test.csv', encoding='utf-8', converters={'text': str}, sep="\t")

df['text'] = df['text'].apply(
    lambda x: word_lemmatizer(
        remove_stopwords(
            tokenizer.tokenize(x.lower())
        )
    )
)

data_count = df['text'].apply(pd.value_counts)

data_count.to_excel("test.xlsx")

创建的这个 excel 文件应该如下所示。

注意:我的屏幕截图中显示的输出是在包含 Dune 书的前 100 个句子的单列 csv 上运行此代码,我没有费心重新创建 OP 屏幕截图中显示的 csv,因为唯一的 -重要的是有一列包含一堆名为“text”的英文单词

所有这些现在都记录在这个答案中,OP 仍然有一个未经证实的评论:

@Phillyclause89 好的,所以我能够输出一个 csv,每个单词都分成自己的单元格,然后我将如何使用值计数?我会在原帖中附上新的 csv。

我的建议是使用pandas.value_counts,正如我在上面的代码示例中所示(在pandas.Series.Apply 中并且不调用它。)从那里您可以使用各种 agg 方法,如 sum 来查找所有单词的计数行:

agg_data_count = data_count.sum().sort_values(0,ascending=False)
agg_data_count.to_excel("sums.xlsx")

打开 sums.xlsx 我们可以得到一个很好的单词列表以及它们在整个数据集中出现的次数:

【讨论】:

  • 也意识到 df['text'].value_counts() 也可以,感谢您的帮助!
猜你喜欢
  • 2020-05-02
  • 2021-01-06
  • 2015-12-26
  • 1970-01-01
  • 2021-02-13
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
相关资源
最近更新 更多