使用pyspark / spark对大型分布式数据集进行采样

时间:2014-07-17 14:17:42

标签: hadoop apache-spark

我在hdfs中有一个文件,它分布在集群中的节点上。

我正试图从这个文件中随机抽取10行。

在pyspark shell中,我使用以下命令将文件读入RDD:

>>> textFile = sc.textFile("/user/data/myfiles/*")

然后我想简单地拿一个样本......关于Spark的一个很酷的事情是有takeSample这样的命令,不幸的是我认为我做错了,因为以下需要很长时间:

>>> textFile.takeSample(False, 10, 12345)

所以我尝试在每个节点上创建一个分区,然后使用以下命令指示每个节点对该分区进行采样:

>>> textFile.partitionBy(4).mapPartitions(lambda blockOfLines: blockOfLines.takeSample(False, 10, 1234)).first()

但这会产生错误ValueError: too many values to unpack

org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/opt/cloudera/parcels/CDH-5.0.2-1.cdh5.0.2.p0.13/lib/spark/python/pyspark/worker.py", line 77, in main
    serializer.dump_stream(func(split_index, iterator), outfile)
  File "/opt/cloudera/parcels/CDH-5.0.2-1.cdh5.0.2.p0.13/lib/spark/python/pyspark/serializers.py", line 117, in dump_stream
    for obj in iterator:
  File "/opt/cloudera/parcels/CDH-5.0.2-1.cdh5.0.2.p0.13/lib/spark/python/pyspark/rdd.py", line 821, in add_shuffle_key
    for (k, v) in iterator:
ValueError: too many values to unpack

如何使用spark或pyspark从大型分布式数据集中采样10行?

3 个答案:

答案 0 :(得分:26)

请尝试使用textFile.sample(false,fraction,seed)takeSample通常会非常慢,因为它calls count() on the RDD。它需要这样做,因为否则它不会均匀地从每个分区获取,基本上它使用计数以及您要求的样本大小来计算分数并在内部调用samplesample很快,因为它只使用一个随机布尔生成器,返回真正的fraction%的时间,因此不需要调用count

此外,我认为这不会发生在您身上,但如果返回的样本量不够大,则会再次调用sample,这显然会降低它的速度。既然您应该对数据的大小有所了解,我建议您调用样本,然后自己将样本缩小到适当的大小,因为您对数据的了解比Spark更多。

答案 1 :(得分:15)

使用样本代替takeSample似乎可以让事情变得相当快:

textFile.sample(False, .0001, 12345)

这个问题是除非你大致了解数据集中的行数,否则很难知道选择正确的分数。

答案 2 :(得分:0)

PySpark 中不同类型的样本

随机抽取 % 的数据进行替换和不替换

PCollection