python optimization nltk

python - ¿Por qué mi función NLTK es lenta al procesar el DataFrame?



optimization (1)

Su nlkt() original nlkt() cada fila 3 veces.

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

Además, cada vez que llama a nlkt() , los reinicia una y otra vez.

  • stopwords.words(''english'')
  • string.punctuation

Estos deberían ser globales.

stoplist = stopwords.words(''english'') + list(string.punctuation)

Pasando por las cosas línea por línea:

val=repr(val)

No estoy seguro de por qué necesitas hacer esto. Pero podría lanzar fácilmente una columna a un tipo str . Esto debe hacerse fuera de su función de preprocesamiento.

Con suerte, esto se explica por sí mismo:

>>> 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'']

Ahora pasando a la siguiente línea:

clean_txt = [word for word in val.split() if word.lower() not in stopwords.words(''english'')]

Usar str.split() es incómodo, debe usar un tokenizador adecuado. De lo contrario, sus signos de puntuación podrían estar atascados con la palabra anterior, p. Ej.

>>> 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'']

También la comprobación de .isdigit() debe verificarse juntos:

>>> 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'']

Poniendo todo junto, su nlkt() debería verse así:

def preprocess(text): return [word for word in word_tokenize(text) if word.lower() not in stoplist and not word.isdigit()]

Y puede usar el DataFrame.apply :

data[''Anylize_Text''].apply(preprocess)

Estoy tratando de ejecutar una función con mis millones de líneas en un conjunto de datos.

  1. Leo los datos de CSV en un marco de datos
  2. Uso la lista desplegable para descartar datos que no necesito
  3. Lo paso a través de una función NLTK en un bucle for.

código:

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

Ahora estoy llamando a la función anterior usando un bucle for para ejecutar por millones de registros. Aunque estoy en un servidor pesado con CPU de 24 núcleos y 88 GB de RAM, veo que el ciclo está tomando demasiado tiempo y no está usando la potencia de cálculo que existe

Estoy llamando a la función anterior así

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)

El código anterior funciona perfectamente bien, demasiado lento cuando tenemos pocos millones de registros. Es solo un registro de muestra en Excel, pero los datos reales estarán en DB que se ejecutarán en unos pocos cientos de millones. ¿Hay alguna forma de acelerar la operación para pasar los datos a través de la función más rápido? ¿Usar más potencia computacional?