Проблема с UDF в Spark — ошибка типа: объект «Столбец» не может быть вызван

#python #python-3.x #dataframe #apache-spark #pyspark

Вопрос:

Привет всем!
У меня есть фрейм данных с 2510765 строками, содержащими обзоры приложений с относительной оценкой и имеющими следующую структуру:

 root
 |-- content: string (nullable = true)
 |-- score: string (nullable = true)

 

Я написал эти две функции, чтобы удалить знаки препинания и удалить смайлики из текста:

 import string

def remove_punct(text):
    return text.translate(str.maketrans('', '', string.punctuation))

 

и

 import re

def removeEmoji(text):
    regrex_pattern = re.compile(pattern = "["
        u"U0001F600-U0001F64F"  # emoticons
        u"U0001F300-U0001F5FF"  # symbols amp; pictographs
        u"U0001F680-U0001F6FF"  # transport amp; map symbols
        u"U0001F1E0-U0001F1FF"  # flags (iOS)
                           "] ", flags = re.UNICODE)
    return regrex_pattern.sub(r'',text)
 

Я использую эту udf функцию для создания функции spark, начиная с тех, которые я определил для удаления знаков препинания и смайликов:

 from pyspark.sql.functions import udf

punct_remove = udf(lambda s: remove_punct(s))

removeEmoji = udf(lambda s: removeEmoji(s))
 

Но я получаю следующую ошибку:

 TypeError                                 Traceback (most recent call last)

<ipython-input-29-e5d42d609b59> in <module>()
----> 1 new_df = new_df.withColumn("content", remove_punct(df_merge["content"]))
      2 new_df.show(5)

<ipython-input-21-dee888ef5b90> in remove_punct(text)
      2 
      3 def remove_punct(text):
----> 4     return text.translate(str.maketrans('', '', string.punctuation))
      5 
      6 

TypeError: 'Column' object is not callable
 

Как это можно решить? Есть ли другой способ заставить пользовательские функции выполняться в фрейме данных?
Спасибо вам 😉

Ответ №1:

Трассировка стека предполагает, что вы вызываете метод python напрямую, а не udf.

remove_punct является простой функцией ванильного Python, в то время punct_remove как является udf, который можно использовать в качестве второго параметра withColumn вызова.

Один из способов решить проблему-использовать punct_remove вместо remove_punct withColumn вызова.

Еще один способ уменьшить вероятность смешения функции Python с udf-использовать @udf аннотацию:

 from pyspark.sql import functions as F
from pyspark.sql import types as T

@F.udf(returnType=T.StringType())
def remove_punct(text):
    return text.translate(str.maketrans('', '', string.punctuation))

df.withColumn("content", remove_punct(F.col("content"))).show()