【问题标题】:Faster way to apply a function over a column in pandas data frame在熊猫数据框中的列上应用函数的更快方法
【发布时间】:2020-03-27 20:48:06
【问题描述】:

我必须将一些多个函数应用于一列以获取二元组列表,但是以我目前使用的方式使用 apply 函数非常慢。有没有办法提高速度?

def remove_stop_words(text):
    cleantext = text.lower()
    cleantext = ' '.join(re.sub(r'[^\w]', ' ', cleantext).strip().split())
    filtered_sentence= ''
    for w in word_tokenize(cleantext):
        if w not in stop_words: 
            filtered_sentence =  filtered_sentence + ' ' + w
    return  filtered_sentence.strip()

def lemmatize(text):
    lemma_word = []
    for w in word_tokenize(text.lower()):
        word1 = wordnet_lemmatizer.lemmatize(w, pos = "n")
        word2 = wordnet_lemmatizer.lemmatize(word1, pos = "v")
        word3 = wordnet_lemmatizer.lemmatize(word2, pos = ("a"))
        lemma_word.append(word3)
    return ' '.join(lemma_word)

def get_ngrams(text, n ):
    n_grams = ngrams(word_tokenize(text), n=2)
    return [ ' '.join(grams) for grams in n_grams]


df['bigrams'] = df.headline.apply(lambda x: get_ngrams(lemmatize(remove_stop_words(x)),n=2))

编辑:(基于评论) 数据框 df 包含 2 列 - 1. 标题 2. 情绪得分

headline - 这是新闻标题,基本上是我必须在其上应用函数来获取标题的二元组的文本

情绪分数 - 我必须在 df 数据帧中也保留分数,因此需要在同一数据帧中获得一个名为“bigram”的列

Dataframe df

【问题讨论】:

  • 您将无法绕过apply 来应用这些功能。因此,除非您设法加快这些速度,否则您可能需要考虑 multiprocessing,以并行化流程
  • 你能分享所有相关的代码和数据吗?请参阅:minimal reproducible example.
  • 我已经描述了数据框并添加了它的外观图片,希望它能给你足够的想法
  • @WhiteWalker 帖子本身中的数据,请不要作为图像。

标签: python pandas nlp


【解决方案1】:

我发现最好的方法是使用多处理库并行化进程。

import numpy as np
import pandas as pd
import re
import time
from nltk import pos_tag, word_tokenize
from nltk.util import ngrams
import nltk
from nltk.corpus import stopwords
import nltk.data
from nltk.stem import WordNetLemmatizer
import random
from multiprocessing import  Pool


def get_ngrams(text, n=2 ):
    n_grams = ngrams(text.split(), n=n)
    return [ ' '.join(grams) for grams in n_grams]


def bigrams(df):
    df['bigrams'] = df.headline.apply(lambda x: get_ngrams(lemmatize(remove_stop_words(x)),n=2))
    return df

def parallelize_dataframe(df, func, n_cores=20):
    df_split = np.array_split(df, n_cores)
    pool = Pool(n_cores)
    df = pd.concat(pool.map(func, df_split))
    pool.close()
    pool.join()
    return df

df2 = parallelize_dataframe(df, bigrams)
bigramScore = df2.explode('bigrams')

注意:仅当您只有 2-3 个可用内核时,这仅在您有大量可用内核时才有用,这可能不是最佳方法,因为还要考虑并行化进程的开销成本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多