pyspark里mapPartitions的用法

首先是map和mapPartitions的区别

1. map():每次处理一条数据。

2. mapPartitions():每次处理一个分区的数据,这个分区的数据处理完后,原RDD中分区的数据才能释放,可能导致OOM。

优化场景如下:

map(fun)里每次都传入一个参数,访问一次fun(一个url请求链接),这样因为map算子是并发执行,url的并发请求访问数会非常高;所以需要把并发数降下来;考虑先重分区,然后对每个分区用mapPartitions(fun)来处理,每个分区内遍历循环调用url请求,这样可以大致把访问并发数控制在和重分区数一致。

mapPartitions()代码如下:

1. 原本调用map()
def log_data(qc_id):
		list = []
		list.append({json串})
	return list

quality_log_rdd = log_data_version_df.rdd

-------------------------------------------------------
quality_log_rdd = quality_log_rdd.map(lambda x : log_data(x))
-------------------------------------------------------

quality_log_list = []
        for itemArr in quality_log_rdd.collect():
            if itemArr is None or len(itemArr) == 0:
                continue
            for item in itemArr:
                quality_log_list.append(item)

quality_log_df = self.sqlContext.createDataFrame(quality_log_list)
2. 优化后调用mapPartitions()
def log_data(qc_id):
		list = []
		list.append({json串})
	return list

quality_log_rdd = log_data_version_df.rdd

-------------------------------------------------------
def ite_log_data(partitionData):
    parDataList = []
    for pardata in partitionData:
        parDataList.append(log_data(pardata))
    return parDataList

quality_log_rdd = quality_log_rdd.repartition(20).mapPartitions(ite_log_data)
--------------------------------------------------------

quality_log_list = []
        for itemArr in quality_log_rdd.collect():
            if itemArr is None or len(itemArr) == 0:
                continue
            for item in itemArr:
                quality_log_list.append(item)

quality_log_df = self.sqlContext.createDataFrame(quality_log_list)

---里就是mapPartitions()的用法,先定义一个函数ite_log_data,然后再在mapPartitions里调用即可;

值得注意的是,最后返回的结果,map()处理和mapPartitions()处理的rdd里的数据解析起来是完全一致的,都是[{json1}], [{json2}], [{json3}]...[{jsonn}]这种数据集。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PySpark中,mapPartitions也是一个转换操作,用于对RDD中的每个分区进行批量处理。与Scala中的mapPartitions相似,它接收一个函数作为参数,该函数将迭代器作为输入,并返回一个新的迭代器作为输出。 下面是一个示例代码,展示了如何在PySpark中使用mapPartitions操作: ```python from pyspark import SparkContext # 创建SparkContext对象 sc = SparkContext("local", "mapPartitions example") # 创建一个包含5个元素的RDD,并指定2个分区 rdd = sc.parallelize([1, 2, 3, 4, 5], 2) # 定义一个函数,对每个分区的元素进行求和 def sum_partition(iter): partition_sum = sum(iter) return [partition_sum] # 使用mapPartitions操作对每个分区进行求和 result = rdd.mapPartitions(sum_partition) # 收集结果并打印 print(result.collect()) # 输出: [3, 12] ``` 在上述示例中,我们首先创建了一个包含5个元素的RDD,并指定分为2个分区。然后,我们定义了一个名为sum_partition的函数,该函数对每个分区的元素进行求和,并返回一个包含每个分区总和的列表。最后,我们使用mapPartitions操作将sum_partition函数应用于RDD的每个分区,并通过collect操作将结果收集到驱动程序,并打印出来。 值得注意的是,PySpark中的mapPartitions操作返回的是一个新的RDD,而不是一个迭代器。因此,我们可以使用RDD的其他转换和动作操作对结果进行进一步处理和操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值