我有一个示例Python类
class bean :
def __init__(self, puid, pogid, bucketId, dt, at) :
self.puid = puid
self.pogid = pogid
self.bucketId = bucketId
self.dt = (datetime.datetime.today() - datetime.datetime.strptime(dt, "%Y-%m-%d %H:%M:%S")).days
self.absdt=dt
self.at = at
现在我知道在Java中创建一个可序列化的类,我们只需要扩展Serializable和ovverride一些方法,生活很简单。虽然Python是如此简单但我无法找到一种方法来序列化这个类的对象。
这个类应该可以通过网络进行序列化,因为这个调用的对象是apache spark,它通过网络分配对象。
最好的方法是什么。
我还发现了this,但不知道这是否是最佳方式。
我也读过
无法对类,函数和方法进行pickle - 如果你挑选一个对象,那么对象的类不会被pickle,只是一个标识它所属的类的字符串。
这是否意味着这些类不能被序列化?
PS:由于数据量巨大,因此该类将有数百万个对象。因此,请提供2个解决方案,一个最简单,最有效的方法。
编辑:
为了澄清,我必须使用像
这样的东西def myfun():
**Some Logic **
t1 = bean(<params>)
t2 = bean(<params2>)
temp = list()
temp.append(t1)
temp.append(t2)
return temp
现在最终如何调用
PairRDD.map(myfun).collect()
抛出异常
<function __init__ at 0x7f3549853c80> is not JSON serializable
答案 0 :(得分:3)
首先,对于你的例子,泡菜将很有效。 pickle没有序列化&#34;功能&#34;,它只序列化&#34;数据&#34; - 所以,如果你有类型的尝试在远程脚本上序列化,即如果你有类型&#34; bean&#34;在接收端导入 - 您可以使用pickle或cpickle,一切都会正常工作。上述免责声明声明它不保留课程的代码,这意味着如果您没有它在接收端导入,泡菜不会为你工作。
所有跨语言序列化解决方案(即json
,xml
)永远不会提供转移类&#34;代码&#34;因为没有合理的方式来代表它。如果你在两端都使用相同的语言(比如这里),有办法让它工作 - 例如你可以marshal对象,腌制结果,发送它,接收端接收,unpickle和unmarshal,你有一个对象的功能 - 这实际上是发送代码和eval()
- 它在接收端..
以下是基于您的酸洗对象类的简单示例:
<强> test.py 强>
import datetime
import pickle
class bean:
def __init__(self, puid, pogid, bucketId, dt, at) :
self.puid = puid
self.pogid = pogid
self.bucketId = bucketId
self.dt = (datetime.datetime.today() - datetime.datetime.strptime(dt, "%Y-%m-%d %H:%M:%S")).days
self.absdt=dt
self.at = at
def whoami(self):
return "%d %d"%(self.puid, self.pogid)
def myfun():
t1 = bean(1,2,3,"2015-12-31 11:50:25",4)
t2 = bean(5,6,7,"2015-12-31 12:50:25",8)
tmp = list()
tmp.append(t1)
tmp.append(t2)
return tmp
if __name__ == "__main__":
with open("test.data", "w") as f:
pickle.dump(myfun(), f)
with open("test.data", "r") as f2:
obj = pickle.load(f2)
print "|".join([bean.whoami() for bean in obj])
运行它:
ben@ben-lnx:~$ python test.py
1 2|5 6
所以只要您拥有导入的类型,就可以看到pickle工作..
答案 1 :(得分:1)
只要您传递给__init__
(puid
,pogid
,bucketId
,dt
,at
)的所有参数都可以序列化应该不需要任何额外的步骤。如果您遇到任何问题,很可能意味着您没有在群集上正确分发模块。
虽然PySpark会自动分配闭包内引用的变量和函数,但是分配模块,库和类是您的责任。如果简单类创建一个单独的模块并通过SparkContext.addPyFile
传递它应该就够了:
# https://www.python.org/dev/peps/pep-0008/#class-names
from some_module import Bean
sc.addPyFile("some_module.py")