所有字符串表都会导致 PickleException:ClassDict 构造的预期零参数(用于 numpy.dtype)
Posted
技术标签:
【中文标题】所有字符串表都会导致 PickleException:ClassDict 构造的预期零参数(用于 numpy.dtype)【英文标题】:All strings table leads to PickleException: expected zero arguments for construction of ClassDict (for numpy.dtype) 【发布时间】:2021-08-11 17:56:56 【问题描述】:我是 pyspark 的新手,在 python 和 spark 之间转换数据类型。我想将 python 列表转换为 pyspark 数据框,但没有这样做。我搜索了类似的错误,但仍然无法弄清楚。有人可以提供指导吗?任何帮助表示赞赏。
我已创建此列表 output_list
作为数据块中的输出。该列表如下所示:
['id': 'abcd342', 'v1': 'Mickey Mouse', 'v2': 'USA', 'v3': 'Male', 'v4': 'NY', 'v5': 'Artist', 'v6': 'Garden', 'v7': 'Donald', 'v8': 'Duck',
'id': 'b4fcef', 'v1': 'Harry Potter', 'v2': 'Britain', 'v3': 'Male', 'v4': 'London', 'v5': 'Compliance Officer', 'v6': 'Dining Room', 'v7': 'Sally', 'v8': 'Human']
然后我尝试使用以下代码将其转换为 pyspark 数据帧:
from pyspark.sql import SparkSession
from pyspark.sql.types import ArrayType, StructField, StructType, StringType, IntegerType, DecimalType
from decimal import Decimal
appName = "Output results"
master = "local"
# Create Spark session
spark = SparkSession.builder \
.appName(appName) \
.master(master) \
.getOrCreate()
# Create a schema for the dataframe
schema = StructType([
StructField('id', StringType(), True),
StructField('v1', StringType(), True),
StructField('v2', StringType(), True),
StructField('v3', StringType(), True),
StructField('v4', StringType(), True),
StructField('v5', StringType(), True),
StructField('v6', StringType(), True),
StructField('v7', StringType(), True),
StructField('v8', StringType(), True)
])
# Convert list to RDD
output_rdd = spark.sparkContext.parallelize(output_list)
# Create data frame
output_df = spark.createDataFrame(output_rdd,schema)
print(output_df.schema)
print(type(output_df))
output_df.show()
然后我得到的结果包括这样的错误消息:
output_df:pyspark.sql.dataframe.DataFrame
id:string
v1:string
v2:string
v3:string
v4:string
v5:string
v6:string
v7:string
v8:string
StructType(List(StructField(id,StringType,true),StructField(v1,StringType,true),StructField(v2,StringType,true),StructField(v3,StringType,true),StructField(v4,StringType,true),StructField(v5,StringType,true),StructField(v6,StringType,true),StructField(v7,StringType,true),StructField(v8,StringType,true)))
<class 'pyspark.sql.dataframe.DataFrame'>
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 31.0 failed 4 times, most recent failure: Lost task 0.3 in stage 31.0 (TID 127) (10.201.235.14 executor 1): net.razorvine.pickle.PickleException: expected zero arguments for construction of ClassDict (for numpy.dtype)
Py4JJavaError Traceback (most recent call last)
<command-88414643813881> in <module>
32 print(output_df.schema)
33 print(type(output_df))
---> 34 output_df.show()
/databricks/spark/python/pyspark/sql/dataframe.py in show(self, n, truncate, vertical)
488 """
489 if isinstance(truncate, bool) and truncate:
--> 490 print(self._jdf.showString(n, 20, vertical))
491 else:
492 print(self._jdf.showString(n, int(truncate), vertical))
/databricks/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py in __call__(self, *args)
1302
1303 answer = self.gateway_client.send_command(command)
-> 1304 return_value = get_return_value(
1305 answer, self.gateway_client, self.target_id, self.name)
1306
奇怪的是我尝试了另一种方法来执行相同的过程,并且它有效。我首先打印出格式列表之类的 json,将列表复制并粘贴到一个新变量中。使用这个新变量,它可以毫无问题地转换为 pyspark 数据框。我检查了output_list
和output_list_2
的类型,都是<class 'list'>
。我应该改变什么才能使我的原始流程正常工作?这是我的测试代码:
output_list_2 = ['id': 'abcd342', 'v1': 'Mickey Mouse', 'v2': 'USA', 'v3': 'Male', 'v4': 'NY', 'v5': 'Artist', 'v6': 'Garden', 'v7': 'Donald', 'v8': 'Duck',
'id': 'b4fcef', 'v1': 'Harry Potter', 'v2': 'Britain', 'v3': 'Male', 'v4': 'London', 'v5': 'Compliance Officer', 'v6': 'Dining Room', 'v7': 'Sally', 'v8': 'Human']
from pyspark.sql import SparkSession
from pyspark.sql.types import ArrayType, StructField, StructType, StringType, IntegerType, DecimalType
from decimal import Decimal
appName = "Output results"
master = "local"
# Create Spark session
spark = SparkSession.builder \
.appName(appName) \
.master(master) \
.getOrCreate()
# Create a schema for the dataframe
schema = StructType([
StructField('id', StringType(), True),
StructField('v1', StringType(), True),
StructField('v2', StringType(), True),
StructField('v3', StringType(), True),
StructField('v4', StringType(), True),
StructField('v5', StringType(), True),
StructField('v6', StringType(), True),
StructField('v7', StringType(), True),
StructField('v8', StringType(), True)
])
# Convert list to RDD
output_rdd = spark.sparkContext.parallelize(output_list_2)
# Create data frame
output_df = spark.createDataFrame(output_rdd,schema)
print(output_df.schema)
print(type(output_df))
output_df.show()
仍然不知道为什么它不起作用。但是,我找到了另一种方法来完成这项工作。不完美,但会完成工作。这是我的解决方案:
# Create data frame
# *Old way*
# output_df = spark.createDataFrame(output_rdd,schema)
# print(output_df.schema)
# print(type(output_df))
# output_df.show()
# *New way*
output_df = sqlContext.read.json(output_rdd)
print(type(output_df))
output_df.show()
catch 是输出的顺序。由于它不使用架构,因此列会自动按字母顺序排列。
【问题讨论】:
您好,您有什么理由必须创建 RDD 作为 Dataframe 的中间步骤吗? @BgRva 嗨,我正在按照一些示例进行操作。我愿意接受其他选择。 【参考方案1】:当您像这样初始化数据时,它会被初始化为字典的列表。
liet_1 = ['id': 'abcd342', 'v1': 'Mickey Mouse',
'id': 'b4fcef', 'v1': 'Harry Potter']
但是,如果将数据初始化为元组的列表,则可以直接初始化DataFrame,只要每个元组中的项目顺序相同即可。架构将定义列名:
list_2 = [('abcd342', 'Mickey Mouse'),
('b4fcef', 'Harry Potter')]
schema2 = StructType([
StructField('id', StringType(), True),
StructField('v1', StringType(), True)
])
df = spark.createDataFrame(list_2, schema2 )
干杯
【讨论】:
嗨@BgRva,感谢您的支持。我更新了问题中的描述。输入是一个列表,而不是一个 json 文件。它只是遵循相同的格式[, , ..., ]
。很抱歉之前的混乱。您能否根据此更新提供建议?
我找到了另一种实现目标的方法。不完美,但工作。请在帖子中查看我的更新。不过,我仍然期待您的意见。提前谢谢!
谢谢。是的,它是在字典列表中创建的。为什么它不起作用,这很令人困惑。但是非常感谢您的讨论!它鼓舞人心。以上是关于所有字符串表都会导致 PickleException:ClassDict 构造的预期零参数(用于 numpy.dtype)的主要内容,如果未能解决你的问题,请参考以下文章