После изрядного количества комментариев в комментариях с OP я решил, что будет лучше всего обобщить мои предложения здесь.
Первая проблема заключается в том, что в 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
является методом на месте, а это не так. Чтобы они действительно изменили объект pandas.DataFrame
, назначенный df
, здесь нужно использовать присваивание:
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)
Кроме того, лямбда-выражение требуется только в первом вызове для выполнения части x.lower()
, поскольку remove_stopwords
и word_lemmatizer
оба принимают значение как есть, нам не нужны дополнительные лямбда-выражения. Наконец, все три строки можно объединить в один вызов pandas.Series.apply
, поскольку эти функции применяются к одним и тем же значениям:
df['text'] = df['text'].apply(
lambda x: word_lemmatizer(
remove_stopwords(
tokenizer.tokenize(x.lower())
)
)
)
Полный код, который, я надеюсь, OP смог собрать из моих комментариев, должен выглядеть примерно так:
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 должен выглядеть примерно так.
Примечание. Результат, показанный на моем снимке экрана, получен в результате выполнения этого кода в CSV-файле с одним столбцом, который состоит из первых 100 предложений книги «Дюна». потрудитесь воссоздать csv, показанный на скриншоте OP, поскольку единственное, что должно иметь значение, это наличие столбца с кучей английских слов с именем «текст»
Теперь, когда все это задокументировано в этом ответе, у 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, мы можем получить хороший список наших слов и сколько раз они встречаются во всем наборе данных:
person
Phillyclause89
schedule
24.06.2020
'amazonfresh-test.csv'
? - person Phillyclause89   schedule 23.06.2020'test'
вdata_count = df['test'].apply(pd.value_counts())
? Я не вижу это как столбец, существующий в вашем исходном CSV, и я не вижу, чтобы вы создавали такой столбец где-либо в своем коде, прежде чем использовать для него методpandas.Series.apply
. - person Phillyclause89   schedule 23.06.2020pandas.value_counts
. Естьpandas.Series.value_counts
, но я не уверен, что это то, что вы хотите здесь использовать. вы просто пытаетесь подсчитать количество каждого токена, оставшегося после удаления стоп-слов? может попробовать:data_count = df['text'].apply(lambda x: len(x))
? - person Phillyclause89   schedule 23.06.2020data_count = df['text'].apply(pd.value_counts())
или в этой строке есть другие опечатки? как написано, я получаюTypeError: value_counts() missing 1 required positional argument: 'values'
, когда пытаюсь запустить его. Как вы определили, что эта линия является вашим узким местом? Вы уверены, что это не один из других.apply
вызовов? - person Phillyclause89   schedule 23.06.2020pandas.Series.apply
по умолчанию не является методом на месте. Я думаю, вы хотите сделатьdf['text'] = df['text'].apply(func)
в тех трех строках, где, похоже, вы хотите токонизировать и отфильтровать данные в текстовом столбце. 2) Я думаю, вы хотите удалить вызывающую функцию из функцииpd.value_counts
в строкеdata_count = df['test'].apply(pd.value_counts())
. попробовать сделатьdata_count = df['test'].apply(pd.value_counts)
? - person Phillyclause89   schedule 23.06.2020