尝试通过Spark-Submit或Zeppelin运行一些代码时出现以下错误:" _pickle.PicklingError:__ newobj __ args中的args [0]错误的类"
我已经查看了同样问题的帖子,对这个问题有很多了解。
回溯(包含在下面)指向我使用的其中一个udf:
udf_stop_words = udf(stop_words, ArrayType(StringType()))
def stop_words(words):
return list(word.lower() for word in words if word.lower() not in stopwords.words("english"))
函数的输入和输出都是字符串列表。这些是来自输入的3行:
[Row(split_tokenized_activity_description = [' A','令人愉快的',' 45', '分钟'瑞典','风格','按摩']), 行(split_tokenized_activity_description = [' A','更多','激烈', ' 45''分钟','版本','',' a','瑞典& #39;,' style',' massage']), 行(split_tokenized_activity_description = [' A','放松',' 45', '分钟'瑞典','风格','按摩'])
这是我正在使用的代码片段。
def special_car(x):
# remove the special character and replace them with the stop word " " (space)
return [re.sub('[^A-Za-z0-9]+', ' ', x)]
# Create UDF from function
udf_special_car = udf(special_car, ArrayType(StringType()))
# Function to remove stops words
def stop_words(words):
return list(word.lower() for word in words if word.lower() not in stopwords.words("english"))
udf_stop_words = udf(stop_words, ArrayType(StringType()))
# Load in data
df_tags = spark.sql("select * from database")
# Remove special Characters
df1_tags = df_tags.withColumn('tokenized_name', udf_special_car(df_tags.name))
df2_tags = df1_tags.withColumn('tokenized_description', udf_special_car(df1_tags.description))
# Select only relevent columns
df3_tags = df2_tags.select(['tag_id', 'tokenized_name', 'tokenized_description'])
# Tokenize tag_name and tag_desc (Seperate on spaces) (This uses the pyspark.sql.split function)
df4_tags = df3_tags.withColumn('split_tokenized_name', split(df3_tags['tokenized_name'].getItem(0), ' '))
df5_tags = df4_tags.withColumn('split_tokenized_description', split(df3_tags['tokenized_description'].getItem(0), ' '))
# Select only relevent columns
df6_tags = df5_tags.select(['tag_id', 'split_tokenized_name', 'split_tokenized_description'])
# Remove Stop words
df7_tags = df6_tags.withColumn('stop_words_tokenized_name', udf_stop_words(df6_tags.split_tokenized_name))
df8_tags = df7_tags.withColumn('stop_words_tokenized_description', udf_stop_words(df7_tags.split_tokenized_description))
奇怪的是,通过Zeppelin运行我的代码的前两个时间我得到了错误,但是在第3次尝试之后,它运行得很好,输出就是我期望的结果。但Zeppelin仅用于测试;我需要让它通过Spark-Submit运行。
Traceback(最近一次调用最后一次):文件 " /tmp/testing_test.py" ;,第262行,in udf_stop_words = udf(stop_words,ArrayType(StringType()))文件" /usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/functions.py" ;, line 1872年,在udf文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/functions.py" ;, line 1830年,在 init 文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/functions.py" ;, line 1835年,在_create_judf文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/functions.py" ;, line 1815年,在_wrap_function文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/rdd.py" ;,第2359行,在 _prepare_for_python_RDD文件" /usr/lib/spark/python/lib/pyspark.zip/pyspark/serializers.py" ;, line 460,在转储文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/cloudpickle.py" ;, line 703,在转储文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/cloudpickle.py" ;, line 147,在转储文件" /home/hadoop/anaconda/lib/python3.6/pickle.py"中, 409行,在转储中 self.save(obj)File" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第476行,保存 f(self,obj)#使用显式自我文件" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第736行调用未绑定方法 save_tuple 保存(元素)文件" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第476行,保存 f(self,obj)#使用显式自我文件调用未绑定方法" /usr/lib/spark/python/lib/pyspark.zip/pyspark/cloudpickle.py" ;, line 248,在save_function文件中 " /usr/lib/spark/python/lib/pyspark.zip/pyspark/cloudpickle.py" ;, line 296,在save_function_tuple文件中 " /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第476行,保存 f(self,obj)#使用显式自我文件" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第821行调用未绑定方法 save_dict self._batch_setitems(obj.items())File" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第852行,在 _batch_setitems 保存(v)文件" /home/hadoop/anaconda/lib/python3.6/pickle.py" ;,第521行,保存 self.save_reduce(obj = obj,* rv)File" /usr/lib/spark/python/lib/pyspark.zip/pyspark/cloudpickle.py" ;, line 564,在save_reduce中 _pickle.PicklingError:来自 newobj args的args [0]有错误的类
我已经尝试了几个方法来解决这个问题,但没有一个能够解决这个问题。它们都返回相同的错误。
我尝试将udf更改为单行lambda函数:
udf(lambda words: list(word.lower() for word in words if word.lower() not in stopwords.words('english')), ArrayType(StringType())).
我尝试更改udf以返回字符串:
udf_stop_words = udf(stop_words, StringType())
并将udf更改为匹配。
def stop_words(words):
return str(word.lower() for word in words if word.lower() not in stopwords.words('english'))
我试图将它定义为具有以下两者的StructType:
udf_stop_words = udf(stop_words, StructType([StructField("words", ArrayType(StringType()), False)]))
和
udf_stop_words = udf(stop_words, StructType([StructField("words", StringType(), False)])).
我也尝试了上述的许多组合。
答案 0 :(得分:0)
返回类型应为function git_merge_squash() {
git merge --squash "$1"
shift
git commit -m "$(echo $'\n'"$*" | tr . \\n | tr - ' ')"
}
alias gmrs=git_merge_squash
。
我不确定这一点,但问题可能来自您未在节点上安装ArrayType(StringType())
的事实(或者nltk
corpus
从未在节点上下载)。由于在stopwords
内调用stopwords.words("english")
就像在节点上调用它一样,因此它可能会失败,因为它无法找到语料库。
由于UDF
只是一个列表,您应该在驱动程序上调用它,然后将其广播到节点:
stopwords.words("english")
答案 1 :(得分:0)
我有类似的问题。在我的情况下,异常被抛出,因为我在我的spark脚本本身中定义了一个类。它是通过创建包含类定义和方法的单独.py文件来解决的。然后通过sc.addPyFile(path)
并最后from FileName import *
将该脚本添加到您的脚本中。