python - 为什么我的 NLTK 函数在处理 DataFrame 时很慢?

标签 python optimization nltk

我正在尝试使用数据集中的百万行来运行一个函数。

  • 我从数据框中的 CSV 读取数据
  • 我使用下拉列表删除不需要的数据
  • 我在 for 循环中通过 NLTK 函数传递它。

  • 代码:
    def nlkt(val):
        val=repr(val)
        clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
        nopunc = [char for char in str(clean_txt) if char not in string.punctuation]
        nonum = [char for char in nopunc if not char.isdigit()]
        words_string = ''.join(nonum)
        return words_string
    

    现在我正在使用 for 循环调用上述函数来运行数百万条记录。即使我在一个带有 24 核 cpu 和 88 GB Ram 的重量级服务器上,我看到循环花费了太多时间并且没有使用那里的计算能力

    我像这样调用上面的函数
    data = pd.read_excel(scrPath + "UserData_Full.xlsx", encoding='utf-8')
    droplist = ['Submitter', 'Environment']
    data.drop(droplist,axis=1,inplace=True)
    
    #Merging the columns company and detailed description
    
    data['Anylize_Text']= data['Company'].astype(str) + ' ' + data['Detailed_Description'].astype(str)
    
    finallist =[]
    
    for eachlist in data['Anylize_Text']:
        z = nlkt(eachlist)
        finallist.append(z)
    

    当我们有几百万条记录时,上面的代码工作得很好,只是太慢了。它只是 excel 中的一个示例记录,但实际数据将在 DB 中,该数据库将运行数亿。有什么方法可以加快操作以更快地通过函数传递数据 - 而是使用更多的计算能力?

    最佳答案

    您的原创 nlkt()每行循环 3 次。

    def nlkt(val):
        val=repr(val)
        clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
        nopunc = [char for char in str(clean_txt) if char not in string.punctuation]
        nonum = [char for char in nopunc if not char.isdigit()]
        words_string = ''.join(nonum)
        return words_string
    

    此外,每次您调用 nlkt() 时,你一次又一次地重新初始化这些。
  • stopwords.words('english')
  • string.punctuation

  • 这些应该是全局性的。
    stoplist = stopwords.words('english') + list(string.punctuation)
    

    逐行处理:
    val=repr(val)
    

    我不确定你为什么需要这样做。但是您可以轻松地将列转换为 str类型。这应该在您的预处理功能之外完成。

    希望这是不言自明的:
    >>> import pandas as pd
    >>> df = pd.DataFrame([[0, 1, 2], [2, 'xyz', 4], [5, 'abc', 'def']])
    >>> df
       0    1    2
    0  0    1    2
    1  2  xyz    4
    2  5  abc  def
    >>> df[1]
    0      1
    1    xyz
    2    abc
    Name: 1, dtype: object
    >>> df[1].astype(str)
    0      1
    1    xyz
    2    abc
    Name: 1, dtype: object
    >>> list(df[1])
    [1, 'xyz', 'abc']
    >>> list(df[1].astype(str))
    ['1', 'xyz', 'abc']
    

    现在转到下一行:
    clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
    

    使用 str.split()很尴尬,您应该使用适当的标记器。否则,您的标点符号可能会卡在前面的单词上,例如
    >>> from nltk.corpus import stopwords
    >>> from nltk import word_tokenize
    >>> import string
    >>> stoplist = stopwords.words('english') + list(string.punctuation)
    >>> stoplist = set(stoplist)
    
    >>> text = 'This is foo, bar and doh.'
    
    >>> [word for word in text.split() if word.lower() not in stoplist]
    ['foo,', 'bar', 'doh.']
    
    >>> [word for word in word_tokenize(text) if word.lower() not in stoplist]
    ['foo', 'bar', 'doh']
    

    同时检查 .isdigit()应该一起检查:
    >>> text = 'This is foo, bar, 234, 567 and doh.'
    >>> [word for word in word_tokenize(text) if word.lower() not in stoplist and not word.isdigit()]
    ['foo', 'bar', 'doh']
    

    把你的一切放在一起 nlkt()应该是这样的:
    def preprocess(text):
        return [word for word in word_tokenize(text) if word.lower() not in stoplist and not word.isdigit()]
    

    您可以使用 DataFrame.apply :
    data['Anylize_Text'].apply(preprocess)
    

    关于python - 为什么我的 NLTK 函数在处理 DataFrame 时很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47769818/

    相关文章:

    python - Pandas 将数据重新采样到秒,每约 10 秒进行分组

    matlab - 具有相同标签的列的平均值

    python - 从网页中仅提取有意义的文本

    Python:将 NLTK Stanford POS 标签映射到 WordNet POS 标签

    python - 如何访问继承类的关键字参数默认值

    python - Django Rest Framework 使用 filterset_fields 在 ViewSet 中过滤计算出的 SerializerMethodField()

    python - 在 Python 中查找 Dataframe 子集的特征值

    javascript - 使用 iframe 来提高页面性能是否是一种可接受的方法?

    c - 为什么那些函数调用没有优化?

    python - (为了防止内存错误)如何使用 Tokenize 类在 Keras 中将单词列表热编码为 INTEGER 8 矩阵