一、算子类型判断方法

假定玩算子的攻城狮,都会关心算子的返回值,并且已经明白《什么叫做宽依赖和窄依赖》。
在PySpark中,转换操作(转换算子)返回的结果通常是一个RDD对象或DataFrame对象或迭代器对象,具体返回类型取决于转换操作(转换算子)的类型和参数。
如果需要确定转换操作(转换算子)的返回类型,可以使用Python内置的type()函数来判断返回结果的类型。

1. RDD转换算子后的类型判断

例如,对于一个包含整数的RDD,可以使用以下代码来判断map()操作的返回类型:

from pyspark import SparkContext
sc = SparkContext("local", "map example")
nums = sc.parallelize([1, 2, 3])
result = nums.map(lambda x: x * 2)
print(type(result)) # 输出<class 'pyspark.rdd.PipelinedRDD'>

在上面的代码中,我们使用map()方法对RDD进行映射操作,并使用type()函数来判断其返回类型,从而确定map()操作的返回类型为PipelinedRDD对象,即一个RDD对象。

2. DataFrame对象转换算子后的类型判断

类似地,对于一个DataFrame对象,可以使用以下代码来判断select()操作的返回类型:

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("select example").getOrCreate()
df = spark.read.csv("example.csv", header=True, inferSchema=True)
result = df.select("Name", "Age")
print(type(result)) # 输出<class 'pyspark.sql.dataframe.DataFrame'>

在上面的代码中,我们使用select()方法对DataFrame进行列选择操作,并使用type()函数来判断其返回类型,从而确定select()操作的返回类型为DataFrame对象。

3. 迭代器对象转换后类型判断

对于迭代器对象,可以使用以下代码来判断其返回类型:

from pyspark import SparkContext
sc = SparkContext("local", "iterator example")
nums = sc.parallelize([1, 2, 3])
result = nums.toLocalIterator()
print(type(result)) # 输出<class 'iterator'>

在上面的代码中,使用toLocalIterator()方法将RDD转换为Python迭代器对象,并使用type()函数来判断其返回类型,从而确定toLocalIterator()操作的返回类型为Python迭代器对象。
因此,可以根据需要使用type()函数来判断转换操作(转换算子)的返回类型,并使用相应的方法来处理返回结果。
需要注意的是,在实际应用中,转换操作(转换算子)可能会返回极大的结果,因此应该谨慎使用,并考虑使用其他方法来处理大规模数据。

二、转换算子文字说明

在PySpark中,RDD提供了多种转换操作(转换算子),用于对元素进行转换和操作

  1. map(func):对RDD的每个元素应用函数func,返回一个新的RDD。
  2. filter(func):对RDD的每个元素应用函数func,返回一个只包含满足条件元素的新的RDD。
  3. flatMap(func):对RDD的每个元素应用函数func,返回一个扁平化的新的RDD,即将返回的列表或元组中的元素展开成单个元素。
  4. mapPartitions(func):对每个分区应用函数func,返回一个新的RDD。
  5. mapPartitionsWithIndex(func):对每个分区应用函数func,返回一个新的RDD,其中包含分区的索引和分区中的元素。
  6. sample(withReplacement, fraction, seed):随机抽样RDD中的元素,withReplacement指定是否有放回抽样,fraction指定抽样的比例,seed指定随机数生成器的种子。
  7. union(otherRDD):返回一个包含两个RDD所有元素的新的RDD。
  8. distinct(numPartitions=None):返回一个去重后的新的RDD。
  9. groupByKey(numPartitions=None):将RDD中的元素按键分组,返回一个包含每个键对应的所有值的新的RDD。
  10. reduceByKey(func, numPartitions=None):将RDD中的元素按键分组,对每个键对应的值应用函数func,返回一个包含每个键的结果的新的RDD。
  11. aggregateByKey(zeroValue, seqFunc, combFunc, numPartitions=None):将RDD中的元素按键分组,对每个键对应的值应用seqFunc函数,然后对每个键的结果使用combFunc函数,返回一个包含每个键的最终结果的新的RDD。
  12. sortByKey(ascending=True, numPartitions=None, keyfunc=lambda x: x):按键对RDD中的元素进行排序,返回一个新的RDD。
  13. join(otherRDD, numPartitions=None):将两个RDD中具有相同键的元素进行连接操作,返回一个新的RDD。
  14. cogroup(otherRDD, numPartitions=None):将两个RDD中具有相同键的元素进行分组操作,返回一个包含每个键对应的两个RDD中的所有值的新的RDD。
  15. cartesian(otherRDD):返回两个RDD的笛卡尔积,即所有可能的组合。
  16. pipe(command, env=None, checkCode=False):通过管道调用外部命令,将RDD中的元素作为输入,返回一个新的RDD,其中包含外部命令的输出。
  17. coalesce(numPartitions):将RDD的分区数减少到numPartitions,返回一个新的RDD,可以用于减少数据的复制和移动。
  18. repartition(numPartitions):将RDD的分区数增加到numPartitions,返回一个新的RDD,可以用于增加并行度。

三、转换算子(python代码例子)

1. map(func)

from pyspark import SparkContext
sc = SparkContext("local", "map example")
nums = sc.parallelize([1, 2, 3, 4, 5])
squares = nums.map(lambda x: x*x)
print(squares.collect()) # 输出[1, 4, 9, 16, 25]

2. filter(func)

from pyspark import SparkContext
sc = SparkContext("local", "filter example")
nums = sc.parallelize([1, 2, 3, 4, 5])
even_nums = nums.filter(lambda x: x %! (MISSING)== 0)
print(even_nums.collect()) # 输出[2, 4]

3. flatMap(func)

from pyspark import SparkContext
sc = SparkContext("local", "flatMap example")
words = sc.parallelize(["Hello world", "Goodbye world"])
split_words = words.flatMap(lambda x: x.split(" "))
print(split_words.collect()) # 输出['Hello', 'world', 'Goodbye', 'world']

4. distinct(numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "distinct example")
nums = sc.parallelize([1, 2, 3, 3, 4, 4, 5])
distinct_nums = nums.distinct()
print(distinct_nums.collect()) # 输出[1, 2, 3, 4, 5]

5. groupByKey(numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "groupByKey example")
pairs = sc.parallelize([(1, 2), (2, 3), (1, 4), (3, 5)])
grouped_pairs = pairs.groupByKey()
print(grouped_pairs.collect()) # 输出[(1, <pyspark.resultiterable.ResultIterable object at 0x7f7e744b5e80>), (2, <pyspark.resultiterable.ResultIterable object at 0x7f7e744b5e90>), (3, <pyspark.resultiterable.ResultIterable object at 0x7f7e744b5eb0>)]

6. reduceByKey(func, numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "reduceByKey example")
pairs = sc.parallelize([(1, 2), (2, 3), (1, 4), (3, 5)])
sum_by_key = pairs.reduceByKey(lambda x, y: x + y)
print(sum_by_key.collect()) # 输出[(1, 6), (2, 3), (3, 5)]

7. sortByKey(ascending=True, numPartitions=None, keyfunc=lambda x: x)

from pyspark import SparkContext
sc = SparkContext("local", "sortByKey example")
pairs = sc.parallelize([(1, "apple"), (3, "banana"), (2, "orange")])
sorted_pairs = pairs.sortByKey()
print(sorted_pairs.collect()) # 输出[(1, 'apple'), (2, 'orange'), (3, 'banana')]

8. join(other, numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "join example")
names = sc.parallelize([(1, "Alice"), (2, "Bob"), (3, "Charlie")])
scores = sc.parallelize([(1, 80), (2, 90), (3, 85)])
joined_data = names.join(scores)
print(joined_data.collect()) # 输出[(1, ('Alice', 80)), (2, ('Bob', 90)), (3, ('Charlie', 85))]

9. union(other)

from pyspark import SparkContext
sc = SparkContext("local", "union example")
nums1 = sc.parallelize([1, 2, 3])
nums2 = sc.parallelize([3, 4, 5])
union_nums = nums1.union(nums2)
print(union_nums.collect()) # 输出[1, 2, 3, 3, 4, 5]

10. mapValues(func)

from pyspark import SparkContext
sc = SparkContext("local", "mapValues example")
pairs = sc.parallelize([(1, 2), (2, 3), (3, 4)])
mapped_values = pairs.mapValues(lambda x: x*10)
print(mapped_values.collect()) # 输出[(1, 20), (2, 30), (3, 40)]
from pyspark import SparkContext
sc = SparkContext("local", "mapValues example")
pairs = sc.parallelize([(1, "apple"), (2, "banana"), (3, "orange")])
mapped_values = pairs.mapValues(lambda x: x.upper())
print(mapped_values.collect()) # 输出[(1, 'APPLE'), (2, 'BANANA'), (3, 'ORANGE')]

11. keys()

from pyspark import SparkContext
sc = SparkContext("local", "keys example")
pairs = sc.parallelize([(1, 2), (2, 3), (3, 4)])
keys = pairs.keys()
print(keys.collect()) # 输出[1, 2, 3]

12. values()

from pyspark import SparkContext
sc = SparkContext("local", "values example")
pairs = sc.parallelize([(1, 2), (2, 3), (3, 4)])
values = pairs.values()
print(values.collect()) # 输出[2, 3, 4]

13. cogroup(other, numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "cogroup example")
names = sc.parallelize([(1, "Alice"), (2, "Bob"), (3, "Charlie")])
scores = sc.parallelize([(1, 80), (2, 90), (3, 85), (1, 75)])
cogrouped_data = names.cogroup(scores)
print(cogrouped_data.collect()) # 输出[(1, (<pyspark.resultiterable.ResultIterable object at 0x7ff2a805f780>, <pyspark.resultiterable.ResultIterable object at 0x7ff2a805f748>)), (2, (<pyspark.resultiterable.ResultIterable object at 0x7ff2a805f6d8>, <pyspark.resultiterable.ResultIterable object at 0x7ff2a805f6a0>)), (3, (<pyspark.resultiterable.ResultIterable object at 0x7ff2a805f710>, <pyspark.resultiterable.ResultIterable object at 0x7ff2a805f6a0>))]

14. subtract(other, numPartitions=None)

from pyspark import SparkContext
sc = SparkContext("local", "subtract example")
nums1 = sc.parallelize([1, 2, 3, 4, 5])
nums2 = sc.parallelize([3, 4, 5, 6, 7])
subtracted_nums = nums1.subtract(nums2)
print(subtracted_nums.collect()) # 输出[1, 2]

15. sample(withReplacement, fraction, seed=None)

from pyspark import SparkContext
sc = SparkContext("local", "sample example")
nums = sc.parallelize(range(10))
sampled_nums = nums.sample(False, 0.5)
print(sampled_nums.collect()) # 输出[1, 3, 5, 7]

16. takeOrdered(num, key=None)

from pyspark import SparkContext
sc = SparkContext("local", "takeOrdered example")
nums = sc.parallelize([5, 8, 1, 3, 9, 2])
ordered_nums = nums.takeOrdered(3)
print(ordered_nums) # 输出[1, 2, 3]

17. zip(other)

from pyspark import SparkContext
sc = SparkContext("local", "zip example")
nums1 = sc.parallelize([1, 2, 3])
nums2 = sc.parallelize([4, 5, 6])
zipped_data = nums1.zip(nums2)
print(zipped_data.collect()) # 输出[(1, 4), (2, 5), (3, 6)]

18. mapPartitions(func)

from pyspark import SparkContext
sc = SparkContext("local", "mapPartitions example")
nums = sc.parallelize([1, 2, 3, 4, 5], 2)
def sum_partitions(iterator):
    yield sum(iterator)
sums = nums.mapPartitions(sum_partitions)
print(sums.collect()) # 输出[3, 12]

19. repartition(numPartitions)

from pyspark import SparkContext
sc = SparkContext("local", "repartition example")
nums = sc.parallelize([1, 2, 3, 4, 5], 2)
repartitioned_nums = nums.repartition(4)
print(repartitioned_nums.getNumPartitions()) # 输出4

20. pipe(command, env=None, checkCode=False)

from pyspark import SparkContext
sc = SparkContext("local", "pipe example")
nums = sc.parallelize([1, 2, 3, 4, 5])
result = nums.pipe("head -n 3")
print(result) # 输出1\n2\n3\n

21. coalesce(numPartitions)

from pyspark import SparkContext
sc = SparkContext("local", "coalesce example")
nums = sc.parallelize([1, 2, 3, 4, 5], 5)
coalesced_nums = nums.coalesce(2)
print(coalesced_nums.getNumPartitions()) # 输出2

22. glom()

from pyspark import SparkContext
sc = SparkContext("local", "glom example")
nums = sc.parallelize([1, 2, 3, 4, 5], 2)
glommed_data = nums.glom()
print(glommed_data.collect()) # 输出[[1, 2, 3], [4, 5]]

23. flatMapValues(func)

from pyspark import SparkContext
sc = SparkContext("local", "flatMapValues example")
pairs = sc.parallelize([(1, "apple"), (2, "banana"), (3, "orange")])
mapped_values = pairs.flatMapValues(lambda x: [x, x.upper()])
print(mapped_values.collect()) # 输出[(1, 'apple'), (1, 'APPLE'), (2, 'banana'), (2, 'BANANA'), (3, 'orange'), (3, 'ORANGE')]

24. zipWithIndex()

from pyspark import SparkContext
sc = SparkContext("local", "zipWithIndex example")
nums = sc.parallelize([1, 2, 3, 4, 5])
indexed_nums = nums.zipWithIndex()
print(indexed_nums.collect()) # 输出[(1, 0), (2, 1), (3, 2), (4, 3), (5, 4)]

25. mapPartitionsWithIndex(func)

from pyspark import SparkContext
sc = SparkContext("local", "mapPartitionsWithIndex example")
nums = sc.parallelize([1, 2, 3, 4, 5], 2)
def sum_partitions_with_index(partition_index, iterator):
    yield (partition_index, sum(iterator))
sums_by_partition_index = nums.mapPartitionsWithIndex(sum_partitions_with_index)
print(sums_by_partition_index.collect()) # 输出[(0, 3), (1, 12)]

26. keyBy(func)

from pyspark import SparkContext
sc = SparkContext("local", "keyBy example")
words = sc.parallelize(["apple", "banana", "orange"])
keyed_words = words.keyBy(lambda x: x[0])
print(keyed_words.collect()) # 输出[('a', 'apple'), ('b', 'banana'), ('o', 'orange')]