|--------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 转换算子 | 介绍 |
| map(func) | 返回一个新的分布式数据集,该数据集通过将源数据集中的每个元素传递给函数 func 而形成。 |
| mapToPair(func) | Java/Scala返回一个新的分布式数据集<K,V>,该数据集通过将源数据集中的每个元素传递给函数 func 而形成。 |
| filter(func) | 返回一个新的数据集,该数据集由源数据集中使函数 func 返回值为 true 的那些元素组成。这个操作通常被称为过滤)。 |
| flatMap(func) | 类似于 map,但允许每个输入元素映射到零个或多个输出元素(所以 func 应当返回一个序列,而非单个元素)。 |
| mapPartitions(func,) java/scala mapParitionsToDouble(func) mapPartitionsToPair(func) | 类似于map,但会在RDD的每个分区上单独运行,因此当对类型为T的RDD运行时,func必须是Iterator<T>类型; 场景:需要创建昂贵的外部资源;数据处理逻辑复杂,批量处理收益明显;内存充足,能容纳整个分区数据 缺点:内存占用大,一次加载整个分区的数据到内容;OOM风险,分区数据过大导致内存溢出;灵活性差:无法与map类似逐个处理元素并及时释放内存 该方法除了func之外,还存在一个参数:preservesPartitioning,默认false,是否保留原分区信息,默认的话是不保留,即所有数据shuffle操作。 |
| mapPartitionsWithIndex(func, preservesPartitioning) | mapPartitionsWithIndex 与 mapPartitions 类似,但它还向函数提供一个表示分区索引的整数值。所以func必须是(Int,Iterator<T>)类型->Iterator<U> 第二个参数必填 |
| sample(withReplacement:Boolean ,fraction:Double, seed:Long) | sample 函数用于从数据集中抽取指定比例的样本,支持有放回和无放回两种采样方式,并可以指定随机数生成器种子。 withReplacement:是否放回抽样 fraction:比例 seed:随机数,确保结果可复现,可选可不选 |
| union(otherDataset) | union 函数返回一个新的数据集,包含源数据集和参数数据集的所有元素的并集。 注意:不去重,并且不改变分区 |
| intersection(otherDataset) | intersection 返回一个新的RDD,包含源数据集和参数数据集的公共元素。 交集 。 注意:去重,触发shuffle,将相同key的元素聚合到同一分区 |
| subtranct(otherDataset) | subtract 函数返回一个新的RDD,包含在源数据集中存在但在参数数据集中不存在的元素(即差集)。 注意:去重,触发shuffle,将相同key的元素聚合到同一分区 |
| distinct(nums) | distinct 函数返回一个新的数据集,包含源数据集中的所有不重复元素。它会移除源数据集中的重复元素,确保结果中每个元素都是唯一的。 注意: 触发shuffle: 需要重新分区以将相同元素聚集到同一分区 分区可选: 可以指定输出RDD的分区数量 |
java
// map案例,计算每个元素的长度
JavaRDD<String> rdd = sc.parallelize(Arrays.asList("Tom","Jack","Blank"));
// 1. lambda方法
JavaRDD<Integer> result = rdd.map(x->x.length());
// 2. 匿名函数
JavaRDD<Integer> result = rdd.map(new Function<String, Integer>() {
@Override
public Integer call(String s) throws Exception {
return s.length();
}
});
// 3. 静态方法
public static Integer getLen(String str){
return str.length();
};
JavaRDD<Integer> result = rdd.map(x->getLen(x));
JavaRDD<Integer> result = rdd.map(day07::getLen);
// mapToPair案例
// 1. lambda方法
JavaPairRDD<String,Integer> rdd = sc.mapToPair(x->new Tuple2<String,Integer>(x,1));
// 2. 匿名函数
JavaPairRDD<String,Integer> pairData = rdd.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String s) throws Exception {
return new Tuple2<String, Integer>(s,1);
}
});
// 3. 静态方法
public static Tuple2<String,Integer> getPair(String str){
return new Tuple2<String,Integer>(str,1);
};
JavaPairRDD<String,Integer> result = rdd.mapToPair(day07::getPair);
java
// filter案例,筛选为Tom的数据
// 1. lambda方法
JavaRDD<String> result = rdd.filter(x->"Tom".equals(x))
// 2. 匿名函数
JavaRDD<String> result =rdd.filter(new Function<String, Boolean>() {
@Override
public Boolean call(String s) throws Exception {
return "Tom".equals(s);
}
});
// 3. 静态方法
public static Boolean getData(String str){
return "Tom".equals(str)
};
JavaRDD<String> result = rdd.filter(day07::getData);
JavaRDD<String> result = rdd.filter(x->getData(x));
java
# flatMap(func)
# 如:sc.parallelize(Arrays.asList("Tom Jack","Black Hudi","Jimmy")),需要获取如下:"Tom","Jack","Black","Hudi","Jimmy"序列,可以采用flatMap
# 1. lambda方法
JavaRDD<String> rdd = sc.parallelize(Arrays.asList("Tom Jack","Black Hudi","Jimmy"));
JavaRDD<String> result = rdd.flatMap(x->Arrays.asList(x.split(" ")).iterator());
# 2. 匿名函数
JavaRDD<String> result = rdd11.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterator<String> call(String s) throws Exception {
return Arrays.asList(s.split(" ")).iterator();
}
});
# 3. 静态方法
public static Iterator<String> getFlatMap(String s){
return Arrays.asList(s.split(" ")).iterator();
}
JavaRDD<String> result = rdd.flatMap(day07::getFlatMap)
# 如果采用map的话,最后不会压平
JavaRDD<String[]> result1 = rdd.map(x->x.split(" "));
# ["Tom","Jack"],["Black","Hudi"],["Jimmy"],而flatMap在这个map之后,还需要flat压平操作,返回Tom","Jack","Black","Hudi","Jimmy"
java
# mapPartitions
List<String> dataList = new ArrayList<String>();
for(int i=0;i<10000;i++){dataList.add("user_"+String.valueOf(i));};
JavaRDD<String> rdd = sc.parallelize(dataList,2);
// 1. 匿名函数
JavaRDD<Integer> mapPartitionsRdd = rdd.mapPartitions(new FlatMapFunction<Iterator<String>, Integer>() {
@Override
public Iterator<Integer> call(Iterator<String> stringIterator) throws Exception {
List<Integer> intList = new ArrayList<Integer>();
while(stringIterator.hasNext()){
String data = stringIterator.next();
intList.add(data.length());
}
return intList.iterator();
}
});
// 2. 静态函数
public static Iterator<Integer> mapPartitionsDemo(Iterator<String> strs){
List<Integer> intList = new ArrayList<Integer>();
while(strs.hasNext()){
String data = strs.next();
intList.add(data.length());
}
return intList.iterator();
};
JavaRDD<Integer> mapPartitionsRdd1 = rdd.mapPartitions(day07::mapPartitionsDemo);
// 3. lambda函数
JavaRDD<Integer> mapPartitionsRdd2 = rdd.mapPartitions(iteratorStr->{
List<Integer>intList = new ArrayList<Integer>();
while(iteratorStr.hasNext()){
String str = iteratorStr.next();
intList.add(str.length());
}
return intList.iterator();
});
# mapPartitionsToPair
JavaPairRDD<String,Integer> mapPartitionsToPairRdd= rdd.mapPartitionsToPair(iterX->{
List<Tuple2<String,Integer>> data = new ArrayList<>();
while(iterX.hasNext()){
data.add(new Tuple2<>(iterX.next(),iterX.next().length()));
}
return data.iterator();
},true);
java
# mapPartitionsWithIndex
// 1. 匿名方法
JavaRDD<String> mapPartitionsWithIndexRdd = rdd.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() {
@Override
public Iterator<String> call(Integer integer, Iterator<String> stringIterator) throws Exception {
List<String> strList = new ArrayList<>();
while(stringIterator.hasNext()){
strList.add("index:"+String.valueOf(integer)+":"+stringIterator.next());
}
return strList.iterator();
}
},true);
// 2. lambda函数
JavaRDD<String> mapPartitionsWithIndexRdd = rdd.mapPartitionsWithIndex((index,iterX)>->{
List<String> strList = new ArrayList<>();
while(iterX.hasNext()){
String data = iterX.next();
strList.add("index:"+String.valueOf(index)+":"+data );
}
return strList.iterator();
},true)
// 3. 静态方法
public static Iterator<String> mapPartitionsWithIndexDemo(Integer index,Iterator<String> iterX){
List<String> strList = new ArrayList<>();
while(iterX.hasNext()){
String data = iterX.next();
strList.add("index:"+String.valueOf(index)+":"+data );
}
return strList.iterator();
};
JavaRDD<String> mapPartitionsWithIndexRdd = JavaRDD<String> mapPartitionsWithIndexRdd1 = rdd.mapPartitionsWithIndex(day07::mapPartitionsWithIndexDemo,true);
java
# sample随机抽样
JavaRDD<String> rddSample = rdd.sample(true,0.1,1); // 结果可复现
JavaRDD<String> rddSample = rdd.sample(true,0.1); // 结果不可复现
java
// union(otherRDD)
// 保证rdd1和rdd2数据类型一致
JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList("tom","jack"));
JavaRDD<String> rdd2 = sc.parallelize(Arrays.asList("tom","jack"));
JavaRDD<String> rdd3 = rdd1.union(rdd2);
// subtract(otherRDD)
// 在Rdd1不在rdd2的元素-差集
JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList("tom","jack"));
JavaRDD<String> rdd2 = sc.parallelize(Arrays.asList("tom","blank"));
JavaRDD<String> rdd3 = rdd1.subtract(rdd2);
// intersection(otherRDD)
// 在RDD1并且在RDD2的元素-交集
JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList("tom","jack"));
JavaRDD<String> rdd2 = sc.parallelize(Arrays.asList("tom","blank"));
JavaRDD<String> rdd3 = rdd1.intersection(rdd2);
java
// distinct(num):可选
JavaRDD<String> distinctRDD = rdd.distinct();
python
# python
# map算子
rdd = sc.parallelize(["tom","jack","blank"])
result = rdd.map(lambda x:len(x))
def getLen(str):
return len(str)
result = rdd.map(getLen)
# filter算子
rdd = rdd.filter(lambda x:x=='Tom')
def getData(str):
return str == "Tom"
result = rdd.filter(getData)
# flatMap算子
rdd1 = sc.parallelize(["tom jack","black"])
rdd2 = rdd1.flatMap(lambda x:x.split(" "))
# mapPartitions算子
def mapPartitionDemo(listX:list):
intData = []
for x in listX:
intData.append(len(x))
return intData
rdd1 = rdd.mapPartitions(mapPartitionDemo)
rdd1 = rdd.mapPartitions(lambda iterX:[len(x) for x in iterX])
rdd2 = rdd.mapPartitions(lambda iterX:[(x,len(x)) for x in iterX])
# mapPartitionsWithIndex算子,preservesPartitioning 默认为False,重新划分分区
rdd1 = rdd.mapPartitionsWithIndex(lambda index,iterX:[str(index)+":"+item for item in iterX])
# sample算子
rdd1 = rdd.sample(True, 0.1, 1)
rdd1 = rdd.sample(True, 0)
# union 算子
rdd3 = rdd1.union(rdd2)
# intersection 算子
rdd4 =rdd1.intersection(rdd2)
# subtract 算子
rdd5 = rdd1.subtract(rdd2)
# distinct 算子
rdd6 = rdd1.distinct()