酸洗Spark RDD并将其读入Python

酸洗Spark RDD并将其读入Python,python,apache-spark,pickle,pyspark,Python,Apache Spark,Pickle,Pyspark,我试图通过对Spark RDD进行酸洗来序列化它,并将经过酸洗的文件直接读入Python a = sc.parallelize(['1','2','3','4','5']) a.saveAsPickleFile('test_pkl') 然后,我将test_pkl文件复制到本地。如何将它们直接读入Python?尝试普通pickle包时,尝试读取“test_pkl”的第一个pickle部分时失败: pickle.load(open('part-00000','rb')) Traceback (m

我试图通过对Spark RDD进行酸洗来序列化它,并将经过酸洗的文件直接读入Python

a = sc.parallelize(['1','2','3','4','5'])
a.saveAsPickleFile('test_pkl')
然后,我将test_pkl文件复制到本地。如何将它们直接读入Python?尝试普通pickle包时,尝试读取“test_pkl”的第一个pickle部分时失败:

pickle.load(open('part-00000','rb'))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "/usr/lib64/python2.6/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib64/python2.6/pickle.py", line 970, in load_string
    raise ValueError, "insecure string pickle"
ValueError: insecure string pickle
pickle.load(打开('part-00000','rb'))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib64/python2.6/pickle.py”,第1370行,已加载
返回Unpickler(file.load())
文件“/usr/lib64/python2.6/pickle.py”,第858行,已加载
调度[键](自身)
文件“/usr/lib64/python2.6/pickle.py”,第970行,装入字符串
raise VALUERROR,“不安全的字符串pickle”
ValueError:不安全的字符串pickle

我假设spark使用的pickle方法与python pickle方法不同(如果我错了,请纠正我)。有没有办法从Spark中pickle数据,并从文件中将这个pickle对象直接读入python?

更好的方法可能是在每个分区中pickle数据,对其进行编码,然后将其写入文本文件:

import cPickle
import base64

def partition_to_encoded_pickle_object(partition):
    p = [i for i in partition] # convert the RDD partition to a list
    p = cPickle.dumps(p, protocol=2) # pickle the list
    return [base64.b64encode(p)] # base64 encode the list, and return it in an iterable

my_rdd.mapPartitions(partition_to_encoded_pickle_object).saveAsTextFile("your/hdfs/path/")
将文件下载到本地目录后,可以使用以下代码段将其读入:

# you first need to download the file, this step is not shown
# afterwards, you can use 
path = "your/local/path/to/downloaded/files/"
data = []
for part in os.listdir(path):
    if part[0] != "_": # this prevents system generated files from getting read - e.g. "_SUCCESS"
        data += cPickle.loads(base64.b64decode((open(part,'rb').read())))

问题是格式不是pickle文件。这是一个pickled的SequenceFile。可以在Hadoop和Spark环境中打开,但并不打算在python中使用,而是使用基于JVM的序列化来序列化,在本例中是字符串列表

使用project是可能的。简单到

打开(“/path/to/file”,“rb”)作为f:
打印(火花点火加载(f))

问题是它不是pickle文件,而是包含pickle对象的文件,我不知道Python中有任何针对SequenceFile的积极开发的解析器。这里唯一的问题是加载部分需要将所有数据加载到
data
中的内存中,这可能并不总是可能的。@TG61591正确-如果您在一台机器上读取数据,通常无法从集群中读取所有数据。为了解决这个问题,您可能需要从文件中筛选/收缩/提取所需的数据,例如,
data+=some\u filter\u fx(cPickle.loads(base64.b64 decode((open(part,'rb').read()))