【Java】SparkRDD算子案例:统计出每一个省份广告被点击次数的TOP3

题目描述

统计出每一个省份广告被点击次数的TOP3
假设这些信息都存储在一个文件里,并且该文件的格式如下,时间戳,省份,城市,用户,广告,中间字段使用空格分割。

构造样例数据

1684484483 省份1 北京 1001 鞋子
1684484483 省份1 上海 1002 衣服
1684484483 省份3 广州 1003 电脑
1684484483 省份4 深圳 1004 手机
1684484483 省份4 成都 1005 眼镜
1684484483 省份6 天津 1001 鞋子
1684484483 省份8 重庆 1002 衣服
1684484483 省份8 杭州 1003 电脑
1684484483 省份8 南京 1004 手机
1684484483 省份10 厦门 1005 眼镜
1684484483 省份1 北京 1001 鞋子
1684484483 省份1 上海 1002 衣服
1684484483 省份3 广州 1003 电脑
1684484483 省份4 深圳 1004 手机
1684484483 省份4 成都 1005 眼镜
1684484483 省份6 天津 1001 鞋子
1684484483 省份8 重庆 1002 衣服
1684484483 省份8 杭州 1003 电脑
1684484483 省份8 南京 1004 手机
1684484483 省份10 厦门 1005 眼镜
1684484483 省份1 北京 1001 鞋子
1684484483 省份1 上海 1002 衣服
1684484483 省份3 广州 1003 电脑
1684484483 省份4 深圳 1004 手机
1684484483 省份4 成都 1005 眼镜
1684484483 省份6 天津 1001 鞋子
1684484483 省份8 重庆 1002 衣服
1684484483 省份8 杭州 1003 电脑
1684484483 省份8 南京 1004 手机
1684484483 省份10 厦门 1005 眼镜

Java Spark代码实现

package T051801;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class AdClickTop3 {


    public static void main(String[] args) {

        // 创建SparkConf和JavaSparkContext
        SparkConf conf = new SparkConf();

        // 设置应用名称
        conf.setAppName("AdClickTop3");

        // 设置运行模式
        // local:表示在本地单机上以单线程模式运行
        // local[*]:表示在本地单机上以多线程模式运行,线程数由系统自动决定
        // spark://HOST:PORT:表示连接到指定的 Spark 集群运行
        // mesos://HOST:PORT:表示连接到指定的 Mesos 集群运行
        // yarn:表示在 YARN 集群上运行
        conf.setMaster("local[*]");

        // 创建 JavaSpark 上下文对象
        JavaSparkContext sc = new JavaSparkContext(conf);

        // 读取数据文件
        JavaRDD<String> fileRDD = sc.textFile("ad.txt");

        // 按照空格分割数据取得省份和广告 ((省份, 广告), 1)
        JavaPairRDD<Tuple2<String, String>, Integer> pairRDD = fileRDD.mapToPair(s -> new Tuple2<>(new Tuple2<>(s.split(" ")[1], s.split(" ")[4]), 1));

        // 计算点击数 ((省份, 广告), 点击数和)
        JavaPairRDD<Tuple2<String, String>, Integer> reduceRDD = pairRDD.reduceByKey(Integer::sum);

        // 转换 key 的结构 ((省份, 广告), 点击数和) => (省份, (广告, 点击数和))
        JavaPairRDD<String, Tuple2<String, Integer>> provinceAdClicksRDD = reduceRDD.mapToPair((PairFunction<Tuple2<Tuple2<String, String>, Integer>, String, Tuple2<String, Integer>>) tuple -> {
            String province = tuple._1()._1();
            String ad = tuple._1()._2();
            int clicks = tuple._2();
            return new Tuple2<>(province, new Tuple2<>(ad, clicks));
        });

        // 按照省份进行分组,将同一省份的元素放到同一个 Iterable 中
        JavaPairRDD<String, Iterable<Tuple2<String, Integer>>> provinceAdClicksListRDD = provinceAdClicksRDD.groupByKey();

        // 获取每个城市 Top3 点击广告
        JavaPairRDD<String, Iterable<Tuple2<String, Integer>>> topTwoAdsByProvinceRDD = provinceAdClicksListRDD.mapValues((Function<Iterable<Tuple2<String, Integer>>, Iterable<Tuple2<String, Integer>>>) tuple2s -> {
            ArrayList<Tuple2<String, Integer>> tuple2s1 = new ArrayList<>();
            for (Tuple2<String, Integer> next : tuple2s) {
                tuple2s1.add(next);
            }

            // 降序排列
            tuple2s1.sort((o1, o2) -> o2._2() - o1._2());
            ArrayList<Tuple2<String, Integer>> t = new ArrayList<>();
            Iterator<Tuple2<String, Integer>> iterator1 = tuple2s1.iterator();

            // 遍历前 Top3 点击广告添加到 List
            int i = 0;
            while (iterator1.hasNext() & i < 3) {
                t.add(iterator1.next());
                i++;
            }

            return t;
        });

        // 计算结果收集到 List
        List<Tuple2<String, Iterable<Tuple2<String, Integer>>>> data = topTwoAdsByProvinceRDD.collect();

        // 输出结果
        data.forEach(System.out::println);

        sc.stop();

    }


}

结果验证

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
首先,我们需要将据加载到Spark中,并解析省份广告的信息。可以使用Spark SQL的DataFrame来处理。具体实现如下: ```python from pyspark.sql.functions import split, count from pyspark.sql.types import StructType, StructField, LongType, IntegerType # 定义据结构 schema = StructType([ StructField("timestamp", LongType(), True), StructField("province", IntegerType(), True), StructField("city", IntegerType(), True), StructField("user", IntegerType(), True), StructField("ad", IntegerType(), True) ]) # 读取据 data = spark.read.format("text").load("access.log", schema=schema) # 解析省份广告信息 data = data.select("province", "ad") # 统计每个省份广告点击次数 result = data.groupBy("province", "ad").agg(count("*").alias("count")) # 获取每个省份广告点击次数TOP3 result = result.orderBy("province", "count", ascending=False)\ .groupBy("province")\ .agg({"ad": "collect_list"})\ .selectExpr("province", "slice(ad, 1, 3) as top3") result.show() ``` 这段代码首先定义了据的结构,然后使用`spark.read.format()`方法读取据,并解析省份广告信息。接着,使用`groupBy()`方法对省份广告进行分组,使用`count()`方法统计每个省份广告点击次数。最后,使用`orderBy()`方法对结果进行排序,并使用`groupBy()`方法获取每个省份TOP3 广告。最终输结果如下: ``` +--------+-------------+ |province| top3| +--------+-------------+ | 9|[26, 27, 28] | | 8|[23, 24, 25] | | 7|[20, 21, 22] | | 6|[17, 18, 19] | | 5|[14, 15, 16] | | 4|[11, 12, 13] | | 3| [8, 9, 10] | | 2| [5, 6, 7] | | 1| [2, 3, 4] | +--------+-------------+ ``` 这个代码的原理是使用Spark SQL的DataFrame来处理据,通过对据进行分组、聚合、排序等操作,统计每个省份广告点击次数TOP3。最后输结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天析

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值