3.5.1 基本RDD
受任意数据类型的 RDD 支持的转化操作和行动操作
- Python 演示
- Scala 演示
- Java 演示
针对各个元素的转化操作
- 转化操作 map() 接收一个函数,把这个函数用于 RDD 中的每个元素,将函数的返回结果作为结果 RDD 中对应元素的值。
- 转化操作 filter() 则接收一个函数,并将 RDD 中满足该函数的元素放入新的 RDD 中返回。
- 转化操作 flatMap() 和 map() 类似,我们提供给 flatMap() 的函数被分别应用到了输入 RDD 的每个元素上。
不过返回的不是一个元素,而是一个返回值序列的迭代器。伪集合操作
尽管 RDD 本身不是严格意义上的集合,但它也支持许多数学上的集合操作,比如合并和相交操作。
- 使用 RDD.distinct() 转化操作来生成一个只包含不同元素的新 RDD。
需要注意, distinct() 操作的开销很大,因为它需要将所有数据通过网络进行混洗(shuffle),以确保每个元素都只有一份。 - union(other) ,它会返回一个包含两个 RDD 中所有元素的 RDD。
- intersection(other) 方法,只返回两个 RDD 中都有的元素。
intersection() 在运行时也会去掉所有重复的元素(单个 RDD 内的重复元素也会一起移除)。 intersection() 的性能却要差很多,因为它需要通过网络混洗数据来发现共有的元素。 - subtract(other) 函数接收另一个 RDD 作为参数,返回一个由只存在于第一个 RDD 中而不存在于第二个 RDD 中的所有元素组成的 RDD。
- cartesian(other) 转化操作会返回所有可能的 (a, b) 对,其中 a 是源 RDD 中的元素,而 b 则来自另一个 RDD。
笛卡儿积在我们希望考虑所有可能的组合的相似度时比较有用。
要特别注意的是,求大规模 RDD 的笛卡儿积开销巨大。行动操作
- 行动操作 reduce() 。
它接收一个函数作为参数,这个函数要操作两个 RDD 的元素类型的数据并返回一个同样类型的新元素。
使用 reduce() ,可以很方便地计算出 RDD 中所有元素的总和、元素的个数,以及其他类型的聚合操作 - fold() 和 reduce() 类似,接收一个与 reduce() 接收的函数签名相同的函数,再加上一个“初始值”来作为每个分区第一次调用时的结果。
所提供的初始值应当是你提供的操作的单位元素;也就是说,使用你的函数对这个初始值进行多次计算不会改变结果 - aggregate() 函数则把我们从返回值类型必须与所操作的 RDD 类型相同的限制中解放出来。
使用 aggregate() 时,需要提供我们期待返回的类型的初始值。
然后通过一个函数把 RDD 中的元素合并起来放入累加器。
考虑到每个节点是在本地进行累加的,最终,还需要提供第二个函数来将累加器两两合并。 - 操作 collect() ,它会将整个 RDD 的内容返回。
collect() 通常在单元测试中使用,因为此时 RDD 的整个内容不会很大,可以放在内存中。
使用 collect() 使得 RDD 的值与预期结果之间的对比变得很容易。
由于需要将数据复制到驱动器进程中, collect() 要求所有数据都必须能一同放入单台机器的内存中。 - take(n) 返回 RDD 中的 n 个元素,并且尝试只访问尽量少的分区,因此该操作会得到一个不均衡的集合。
需要注意的是,这些操作返回元素的顺序与你预期的可能不一样。 - 使用 top() 从 RDD 中获取前几个元素。
top() 会使用数据的默认顺序,但我们也可以提供自己的比较函数,来提取前几个元素。 - 使用 foreach() 行动操作来对 RDD 中的每个元素进行操作,而不需要把 RDD 发回本地。