Эффективный способ создания матрицы плотности термина из pandas DataFrame

Я пытаюсь создать матрицу плотности термина из pandas dataframe, поэтому я могу оценить термины, появляющиеся в кадре данных. Я также хочу удержать «пространственный» аспект моих данных (см. Комментарий в конце сообщения для примера того, что я имею в виду).

Я новичок в пандах и NLTK, поэтому я ожидаю, что моя проблема будет разрешима с помощью некоторых существующих инструментов.

У меня есть dataframe, который содержит два интересующих столбца: например, 'title' и 'page'

import pandas as pd import re df = pd.DataFrame({'title':['Delicious boiled egg','Fried egg ','Split orange','Something else'], 'page':[1, 2, 3, 4]}) df.head() page title 0 1 Delicious boiled egg 1 2 Fried egg 2 3 Split orange 3 4 Something else 

Моя цель состоит в том, чтобы очистить текст и передать интересующие вас термины в TDM. Я использую две функции, чтобы помочь мне очистить строки

  import nltk.classify from nltk.tokenize import wordpunct_tokenize from nltk.corpus import stopwords import string def remove_punct(strin): ''' returns a string with the punctuation marks removed, and all lower case letters input: strin, an ascii string. convert using strin.encode('ascii','ignore') if it is unicode ''' return strin.translate(string.maketrans("",""), string.punctuation).lower() sw = stopwords.words('english') def tok_cln(strin): ''' tokenizes string and removes stopwords ''' return set(nltk.wordpunct_tokenize(strin)).difference(sw) 

И одна функция, которая выполняет манипуляцию с dataframe

  def df2tdm(df,titleColumn,placementColumn,newPlacementColumn): ''' takes in a DataFrame with at least two columns, and returns a dataframe with the term density matrix of the words appearing in the titleColumn Inputs: df, a DataFrame containing titleColumn, placementColumn among others Outputs: tdm_df, a DataFrame containing newPlacementColumn and columns with all the terms in df[titleColumn] ''' tdm_df = pd.DataFrame(index=df.index, columns=[newPlacementColumn]) tdm_df = tdm_df.fillna(0) for idx in df.index: for word in tok_cln( remove_punct(df[titleColumn][idx].encode('ascii','ignore')) ): if word not in tdm_df.columns: newcol = pd.DataFrame(index = df.index, columns = [word]) tdm_df = tdm_df.join(newcol) tdm_df[newPlacementColumn][idx] = df[placementColumn][idx] tdm_df[word][idx] = 1 return tdm_df.fillna(0,inplace = False) tdm_df = df2tdm(df,'title','page','pub_page') tdm_df.head() 

Это возвращает

  pub_page boiled egg delicious fried orange split something else 0 1 1 1 1 0 0 0 0 0 1 2 0 1 0 1 0 0 0 0 2 3 0 0 0 0 1 1 0 0 3 4 0 0 0 0 0 0 1 1 

Но при синтаксическом анализе больших наборов (выход из сотни тысяч строк, тысяч столбцов) это очень медленно. Мои два вопроса:

Могу ли я ускорить эту реализацию?

Есть ли какой-нибудь другой инструмент, который я мог бы использовать, чтобы сделать это?

Я хочу удержать «пространственный» аспект моих данных, например, если «яйцо» появляется очень часто на страницах 1-10, а затем снова появляется на страницах 500-520, я хочу это знать.

2 Solutions collect form web for “Эффективный способ создания матрицы плотности термина из pandas DataFrame”

Вы можете использовать CountVectorizer scikit-learn:

 In [14]: from sklearn.feature_extraction.text import CountVectorizer In [15]: countvec = CountVectorizer() In [16]: countvec.fit_transform(df.title) Out[16]: <4x8 sparse matrix of type '<type 'numpy.int64'>' with 9 stored elements in Compressed Sparse Column format> 

Он возвращает термин матрица документов в разреженном представлении, потому что такая матрица обычно огромна и, ну, разрежена.

Для вашего конкретного примера я думаю, что преобразование его обратно в DataFrame все равно будет работать:

 In [17]: pd.DataFrame(countvec.fit_transform(df.title).toarray(), columns=countvec.get_feature_names()) Out[17]: boiled delicious egg else fried orange something split 0 1 1 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 2 0 0 0 0 0 1 0 1 3 0 0 0 1 0 0 1 0 [4 rows x 8 columns] 

herrfz предоставляет способ справиться с этим, но я просто хотел указать, что создание структуры данных плотности термина с использованием набора Python является контрпродуктивным, поскольку набор представляет собой набор уникальных объектов. Вы не сможете захватить счет для каждого слова, только наличие слова для данной строки.

 return set(nltk.wordpunct_tokenize(strin)).difference(sw) 

Чтобы вырезать стоп-слова, вы можете сделать что-то вроде

 tokens_stripped = [token for token in tokens if token not in stopwords] 

после токенизации.

  • Установка rpy2 без прав администратора
  • Преобразование типа данных в R или Python
  • Выполнение R-кода на `python` с помощью SyntaxError: ключевое слово не может быть выражением error Message
  • psycopg2 эквивалентен команде R dbWriteTable и получает больше производительности от кода python
  • Python Pandas для R dataframe
  • Как создать график плотности в matplotlib?
  • Загрузка файлов .RData в Python
  • Топологический анализ данных - с чего начать
  • Точная репликация текстовой предварительной обработки текста в python
  • H2O R api: получение оптимальной модели из сетки
  • Sweave для python
  • Python - лучший язык программирования в мире.