RDD-KV

这里简单描述一下几个rdd,key-values的使用

  • groupByKey
  • reduceByKey
  • aggregateByKey
  • foldByKey
  • combineByKey
  • mapValues
  • join

groupByKey

返回((key,value数组),(key,value数组))

//定义两个kv类型的rdd
val rdd1: RDD[(Int, String)] = spark.sparkContext.makeRDD(Array((1, "r"), (2, "n"), (3, "g")))
val rdd2: RDD[(Int, String)] = spark.sparkContext.makeRDD(Array((1, "e"), (2, "d"), (3, "g")))
val resultRdd: RDD[(Int, Iterable[String])] = rdd1.groupByKey()
//打印结果:((1,("r","e")),(2,("n","d")),(3,("g","g")))

reduceByKey

以相加举例子
返回((key,value的和),(key,value的和))

val rdd1: RDD[(String, Int)] = spark.sparkContext.makeRDD(Array(("r", 1), ("n", 2), ("g", 3), ("r", 5)))
val resultRdd: RDD[(String, Int)] = rdd1.reduceByKey(_ + _)
//打印结果:List((n,2), (r,6), (g,3))

aggregateByKey

第一个参数0代表初始值
第二个参数代表自己分区内计算
第三个参数代表自己分区结果和其他分区结果计算

规则
以zhangsan,两个分区举例子
第一个分区(0 , 5)相加得5
第二个分区(0 , 5)相加得5
5和5相加等于10

val kvRdd: RDD[(String, Int)] = spark.sparkContext.parallelize(Array(("zhangsan", 5), ("zhangsan", 5), ("wangwu", 6), ("zhaoliu", 4), ("tianqi", 3)), 2)
val resultRdd: RDD[(String, Int)] = kvRdd.aggregateByKey(0)(_ + _, _ + _)
//打印结果:List((zhangsan,10), (zhaoliu,4), (tianqi,3), (wangwu,6))

foldByKey

aggregateByKey的简化版
第一个参数,初始值
第二个参数,传一个函数,函数做减法这个就做减法,不需要考虑自己分区和其他分区

val kvRdd: RDD[(String, Int)] = spark.sparkContext.parallelize(Array(("zhangsan", 5), ("zhangsan", 5), ("wangwu", 6), ("zhaoliu", 4), ("tianqi", 3)), 2)
val resultRdd: RDD[(String, Int)] = kvRdd.foldByKey(0)(_ + _)
//打印结果:List((zhangsan,10), (zhaoliu,4), (tianqi,3), (wangwu,6))

combineByKey

可以把原本的v做计算变成元组来计算

做一个计算每个k的v的平均数,需要v的sum和v的count
以zhangsan,两个分区举例子
第一个参数:把5变成(5,1)
第二个参数:把自己分区内的(5,1)和3做相加变成(8,2)
第三个参数:把一分区的(8,2)和二分区的(5,1)变成(13,3)

val kvRdd: RDD[(String, Int)] = spark.sparkContext.parallelize(Array(("zhangsan", 5),("zhangsan", 3), ("zhangsan", 5), ("wangwu", 6), ("zhaoliu", 4), ("tianqi", 3)), 2)
val resultRdd: RDD[(String, (Int, Int))] = kvRdd.combineByKey((_, 1), (x: (Int, Int), y) => (x._1 + y, x._2 + 1), (x: (Int, Int), y: (Int, Int)) => (x._1 + y._1, x._2 + y._2))
//打印结果:List((zhangsan,(13,3)), (zhaoliu,(4,1)), (tianqi,(3,1)), (wangwu,(6,1)))

mapValues

对v来操作

val kvRdd: RDD[(String, Int)] = spark.sparkContext.parallelize(Array(("zhangsan", 5), ("zhangsan", 5), ("wangwu", 6), ("zhaoliu", 4), ("tianqi", 3)), 2)
val resultRdd: RDD[(String, Int)] = kvRdd.mapValues(x => x * 10)
//打印结果:List((zhangsan,50), (zhangsan,50), (wangwu,60), (zhaoliu,40), (tianqi,30))

join

val rdd1: RDD[(String, Int)] = spark.sparkContext.makeRDD(Array(("r", 1), ("n", 2), ("g", 3), ("r", 5)))
val rdd2: RDD[(String, Int)] = spark.sparkContext.makeRDD(Array(("e", 1), ("d", 2), ("g", 3)))
val resultRdd: RDD[(String, (Int, Int))] = rdd1.join(rdd2)
//打印结果:List((g,(3,3)))
### RDD 常用方法及其用法 #### 1. **Transformation 方法** Transformations 是一种懒加载的操作,它们不会立即执行,而是定义了一个新的 RDD。只有当触发 Action 操作时,才会真正执行 Transformation。 - **`map(func)`**: 对 RDD 中的每一个元素应用 `func` 函数,并返回一个新的 RDD[^3]。 ```python rdd = sc.parallelize([1, 2, 3]) mapped_rdd = rdd.map(lambda x: x * 2) ``` - **`filter(func)`**: 返回一个新的 RDD,其中只包含满足条件的元素。 ```python filtered_rdd = rdd.filter(lambda x: x % 2 == 0) ``` - **`flatMap(func)`**: 类似于 `map`,但是它会对每个输入项生成零个或多个输出项。 ```python flat_mapped_rdd = rdd.flatMap(lambda x: range(x)) ``` - **`groupByKey()`**: 当处理键值对形式的数据时,此操作会将具有相同 key 的 value 聚合在一起。 ```python kv_rdd = sc.parallelize([(1, 'a'), (1, 'b'), (2, 'c')]) grouped_rdd = kv_rdd.groupByKey() ``` - **`reduceByKey(func)`**: 和 `reduce` 类似,但它仅应用于每组共享同一个 key 的数据。 ```python reduced_rdd = kv_rdd.reduceByKey(lambda a, b: a + b) ``` - **`join(otherDataset, [numTasks])`**: 执行两个 RDD 的内连接操作,适用于键值对型 RDD[^5]。 ```python other_kv_rdd = sc.parallelize([(1, 'A'), (2, 'B')]) joined_rdd = kv_rdd.join(other_kv_rdd) ``` --- #### 2. **Action 方法** Actions 是实际触发计算的操作,它们会返回最终的结果或者写入外部存储系统。 - **`collect()`**: 将整个 RDD 收集到驱动程序中作为一个列表返回。 ```python result_list = rdd.collect() ``` - **`count()`**: 计算 RDD 中的元素数量。 ```python count_value = rdd.count() ``` - **`take(n)`**: 获取前 n 个元素,通常用于调试目的[^2]。 ```python first_n_elements = rdd.take(5) ``` - **`foreach(func)`**: 对 RDD 中的每个元素逐一调用 func 函数。 ```python rdd.foreach(print) ``` - **`saveAsTextFile(path)`**: 将 RDD 数据保存为文本文件。 ```python rdd.saveAsTextFile("/path/to/output") ``` --- #### 3. **持久化机制** 为了优化性能,可以使用缓存功能来减少重复计算的时间开销。 - **`cache()`**: 缓存当前 RDD 到内存中以便后续重用[^1]。 ```python cached_rdd = rdd.cache() ``` - **`persist(storageLevel)`**: 提供更细粒度的控制选项指定如何以及在哪里存储该 RDD。 ```python from pyspark import StorageLevel persisted_rdd = rdd.persist(StorageLevel.MEMORY_AND_DISK) ``` --- #### 4. **其他重要概念** - **Partitioning**: 每个 RDD 可以划分为若干分区,在集群的不同节点上运行。 - **Lineage Graph**: 如果某个分区丢失,则可以通过其血统图重新构建而无需完全重启作业。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值