복붙노트

[PYTHON] DataFrame을 처리 할 때 NLTK 기능이 느려지는 이유는 무엇입니까?

PYTHON

DataFrame을 처리 할 때 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 기가 바이트 램과 무거운 무게 서버에 나는 루프가 너무 많은 시간을 소요하고 거기에있는 전산 능력을 사용하지 않는 참조하십시오

위의 함수를 다음과 같이 호출합니다.

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에 저장되어 몇백 만 개가 실행됩니다. 함수를 통해 데이터를 전달하는 작업 속도를 향상시킬 수있는 방법이 있습니까? 대신 더 많은 계산 능력을 사용 하시겠습니까?

해결법

  1. ==============================

    1.원래 nlkt ()는 각 행을 3 회 반복합니다.

    원래 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 ()를 호출 할 때마다, 이것들을 몇번이고 다시 초기화하고 있습니다.

    이것들은 글로벌해야합니다.

    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)
    
  2. from https://stackoverflow.com/questions/47769818/why-is-my-nltk-function-slow-when-processing-the-dataframe by cc-by-sa and MIT license