使用PySpark的saveAsHadoopFile()时出现错误,使用saveAsSequenceFile()时出现同样的错误。我需要保存(key,val)的RDD,其中键是字符串,val是LabeledPoint RDD(标签,SparseVector)。错误如下所示。谷歌搜索几个来源似乎我应该能够在IPython笔记本中做到这一点。我需要序列化这个大型RDD,这样我就可以用Java来处理它了,因为一些Spark的MLLib功能还没有用于python。根据这个post,这应该是可行的。
看看这个page我看到了:
_picklable_classes = [
'LinkedList',
'SparseVector',
'DenseVector',
'DenseMatrix',
'Rating',
'LabeledPoint',
]
所以我真的不知道为什么我会收到这个错误。
代码: labeledDataRDD.saveAsSequenceFile(' / TMP / pysequencefile /&#39)
错误:
Py4JJavaError:调用z:org.apache.spark.api.python.PythonRDD.saveAsSequenceFile时发生错误。 :org.apache.spark.SparkException:由于阶段失败而中止作业:阶段527.0中的任务0失败1次,最近失败:阶段527.0中丢失任务0.0(TID 1454,localhost):net.razorvine.pickle.PickleException:构造ClassDict的预期零参数(对于numpy.dtype) at net.razorvine.pickle.objects.ClassDictConstructor.construct(ClassDictConstructor.java:23)
编辑:我发现了这个:
public class More ...ClassDictConstructor implements IObjectConstructor {
12
13 String module;
14 String name;
15
16 public More ...ClassDictConstructor(String module, String name) {
17 this.module = module;
18 this.name = name;
19 }
20
21 public Object More ...construct(Object[] args) {
22 if (args.length > 0)
23 throw new PickleException("expected zero arguments for construction of ClassDict (for "+module+"."+name+")");
24 return new ClassDict(module, name);
25 }
26}
我没有直接使用上面的construct()方法..所以我不知道为什么我尝试的saveAs ..方法在它不需要时传递参数。
编辑2:遵循zero323建议(谢谢)使用了一个小故障。当我尝试使用zero323编写的内容时,我收到错误(见下文)。但是,当我派生出一个更简单的RDD时,它可以工作并将这个更简单的RDD保存到.parquet文件的目录中(将其分解为几个.parquet文件)。更简单的RDD如下:
simplerRDD = labeledDataRDD.map(lambda (k,v): (v.label, v.features))
sqlContext.createDataFrame(simplerRDD, ("k", "v")).write.parquet("labeledData_parquet_file")
尝试保存labeledDataRDD时出错:
/usr/local/Cellar/apache-spark/1.5.1/libexec/python/pyspark/sql/types.pyc in _infer_schema(row)
831 raise TypeError("Can not infer schema for type: %s" % type(row))
832
--> 833 fields = [StructField(k, _infer_type(v), True) for k, v in items]
834 return StructType(fields)
835
/usr/local/Cellar/apache-spark/1.5.1/libexec/python/pyspark/sql/types.pyc in _infer_type(obj)
808 return _infer_schema(obj)
809 except TypeError:
--> 810 raise TypeError("not supported type: %s" % type(obj))
811
812
TypeError: not supported type: <type 'numpy.unicode_'>
答案 0 :(得分:1)
问题的根源不是腌制自己。如果是,你就不会看到<Page Name="Failure">
<Text Name="FailureHeader" X="11" Y="80" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
<Text Name="FailureInstallHeader" X="11" Y="80" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureInstallHeader)</Text>
<Text Name="FailureUninstallHeader" X="11" Y="80" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
<Text Name="FailureRepairHeader" X="11" Y="80" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
<Hypertext Name="FailureLogFileLink" X="11" Y="121" Width="-11" Height="42" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
<Hypertext Name="FailureMessageText" X="22" Y="163" Width="-11" Height="51" FontId="3" TabStop="yes" HideWhenDisabled="yes" ></Hypertext>
<Hypertext Name="CustomMessage" X="22" Y="163" Width="-11" Height="51" FontId="3" TabStop="yes" HideWhenDisabled="yes" >[CustomMessage]</Hypertext>
<Text Name="FailureRestartText" X="11" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
。如果您查看saveAsSequenceFile
文档,则会看到它需要两个步骤:
- Pyrolite用于将pickled Python RDD转换为Java对象的RDD。
- 此Java RDD的键和值将转换为Writable并写出。
醇>
您的程序在第一步失败,但即使它没有,我也不确定什么是预期的Java对象以及如何读回来。
我只是将数据写为Parquet文件,而不是使用序列文件:
<Variable Name="CustomMessage" Value="Hi"/>
<MsiProperty Name="CustomMessage" Value="[CustomMessage]"/>
回读并转换:
session["CustomMessage"]="Please enter valid details";
或者如果您更喜欢类似Java的方法:
net.razorvine.pickle.PickleException
修改强>
一般而言,Spark SQL中不支持NumPy类型作为独立值。如果您在RDD中有Numpy类型,则首先将它们转换为标准Python类型:
from pyspark.mllib.regression import LabeledPoint
rdd = sc.parallelize([
("foo", LabeledPoint(1.0, [1.0, 2.0, 3.0])),
("bar", LabeledPoint(2.0, [4.0, 5.0, 6.0]))])
sqlContext.createDataFrame(rdd, ("k", "v")).write.parquet("a_parquet_file")