Built with Tutify.io

    AIStudyLabs

    Groupby and Aggregations

    Groupby and Aggregations

    Spark Groupby DataFrame

    Similar to SQL “GROUP BY” clause, Spark groupBy() function is used to collect identical data into groups on DataFrame and perform aggregate functions on the grouped data using Java Spark API.

    Syntax:

    groupBy(String col1, String... cols): RelationalGroupedDataset

    When we perform groupBy() on a Spark DataFrame, it returns a RelationalGroupedDataset object that allows us to carry out various aggregate functions:

    Preparing Data & DataFrame

    Before we start, let’s create the DataFrame from a list of data to work with. This DataFrame contains columns "employee_name”, “department”, “state“, “salary”, “age” and “bonus”.

    We will use this Spark DataFrame to run groupBy() on the “department” column and calculate aggregates like minimum, maximum, average, and total salary for each group using min(), max(), and sum() aggregate functions respectively. Finally, we will also see how to group and aggregate on multiple columns.

    import org.apache.spark.sql.Dataset;
    import org.apache.spark.sql.Row;
    import org.apache.spark.sql.SparkSession;
    import org.apache.spark.sql.types.DataTypes;
    import org.apache.spark.sql.RowFactory;
    import java.util.Arrays;
    import static org.apache.spark.sql.functions.col;
    
    SparkSession spark = SparkSession.builder()
            .appName("SparkGroupByExample")
            .master("local")
            .getOrCreate();
    
    List<Row> data = Arrays.asList(
            RowFactory.create("James", "Sales", "NY", 90000, 34, 10000),
            RowFactory.create("Michael", "Sales", "NY", 86000, 56, 20000),
            RowFactory.create("Robert", "Sales", "CA", 81000, 30, 23000),
            RowFactory.create("Maria", "Finance", "CA", 90000, 24, 23000),
            RowFactory.create("Raman", "Finance", "CA", 99000, 40, 24000),
            RowFactory.create("Scott", "Finance", "NY", 83000, 36, 19000),
            RowFactory.create("Jen", "Finance", "NY", 79000, 53, 15000),
            RowFactory.create("Jeff", "Marketing", "CA", 80000, 25, 18000),
            RowFactory.create("Kumar", "Marketing", "NY", 91000, 50, 21000)
    );
    
    Dataset<Row> df = spark.createDataFrame(data, DataTypes.createStructType(Arrays.asList(
            DataTypes.createStructField("employee_name", DataTypes.StringType, false),
            DataTypes.createStructField("department", DataTypes.StringType, false),
            DataTypes.createStructField("state", DataTypes.StringType, false),
            DataTypes.createStructField("salary", DataTypes.IntegerType, false),
            DataTypes.createStructField("age", DataTypes.IntegerType, false),
            DataTypes.createStructField("bonus", DataTypes.IntegerType, false)
    )));
    
    df.show();
    
    +-------------+----------+-----+------+---+-----+
    |employee_name|department|state|salary|age|bonus|
    +-------------+----------+-----+------+---+-----+
    |        James|     Sales|   NY| 90000| 34|10000|
    |      Michael|     Sales|   NY| 86000| 56|20000|
    |       Robert|     Sales|   CA| 81000| 30|23000|
    |        Maria|   Finance|   CA| 90000| 24|23000|
    |        Raman|   Finance|   CA| 99000| 40|24000|
    |        Scott|   Finance|   NY| 83000| 36|19000|
    |          Jen|   Finance|   NY| 79000| 53|15000|
    |         Jeff| Marketing|   CA| 80000| 25|18000|
    |        Kumar| Marketing|   NY| 91000| 50|21000|
    +-------------+----------+-----+------+---+-----+
    

    groupBy and aggregate on DataFrame columns

    Let’s do the groupBy() on the department column of the DataFrame and find the sum of salary for each department using sum() aggregate function.

    df.groupBy("department").sum("salary").show(false);
    
    +----------+-----------+
    |department|sum(salary)|
    +----------+-----------+
    |Sales     |257000     |
    |Finance   |351000     |
    |Marketing |171000     |
    +----------+-----------+
    

    Similarly, we can calculate the number of employees in each department using count()

    df.groupBy("department").count().show(false);
    

    Calculate the minimum salary of each department using min()

    df.groupBy("department").min("salary").show(false);
    

    Calculate the maximum salary of each department using max()

    df.groupBy("department").max("salary").show(false);
    

    Calculate the average salary of each department using avg()

    df.groupBy("department").avg("salary").show(false);
    

    Calculate the mean salary of each department using mean()

    df.groupBy("department").mean("salary").show(false);
    

    groupBy and aggregate on DataFrame multiple columns

    We can also run groupBy and aggregate on two or more DataFrame columns. The example below does a group by on department, state and applies sum() on salary and bonus columns.

    // GroupBy on multiple columns
    df.groupBy("department", "state")
      .sum("salary", "bonus")
      .show(false);
    
    +-----------+-----+------------+----------+
    |department |state|sum(salary) |sum(bonus)|
    +-----------+-----+------------+----------+
    |Finance    |NY   |162000      |34000     |
    |Marketing  |NY   |91000       |21000     |
    |Sales      |CA   |81000       |23000     |
    |Marketing  |CA   |80000       |18000     |
    |Finance    |CA   |189000      |47000     |
    |Sales      |NY   |176000      |30000     |
    +-----------+-----+------------+----------+
    

    Similarly, we can run group by and aggregate on two or more columns for other aggregate functions.

    Running more aggregates at a time

    Using the agg() aggregate function, we can calculate many aggregations at once using Spark SQL aggregate functions such as sum(), avg(), min(), max(), mean(). To use these, we should import "import org.apache.spark.sql.functions.*".

    import static org.apache.spark.sql.functions.*;
    
    df.groupBy("department")
      .agg(
        sum("salary").alias("sum_salary"),
        avg("salary").alias("avg_salary"),
        sum("bonus").alias("sum_bonus"),
        max("bonus").alias("max_bonus")
      )
      .show(false);
    

    This example groups by the department column and calculates sum() and avg() of salary for each department and calculates sum() and max() of bonus for each department.

    +-----------+----------+-----------------+---------+----------+
    |department |sum_salary|avg_salary       |sum_bonus|max_bonus |
    +-----------+----------+-----------------+---------+----------+
    |Sales      |257000    |85666.66666666667|53000    |23000     |
    |Finance    |351000    |87750.0          |81000    |24000     |
    |Marketing  |171000    |85500.0          |39000    |21000     |
    +-----------+----------+-----------------+---------+----------+
    

    Using a filter on aggregate data

    Similar to the SQL “HAVING” clause, in a Spark DataFrame, we can use either the where() or filter() functions to filter the rows of aggregated data.

    df.groupBy("department")
      .agg(
        sum("salary").alias("sum_salary"),
        avg("salary").alias("avg_salary"),
        sum("bonus").alias("sum_bonus"),
        max("bonus").alias("max_bonus")
      )
      .where(col("sum_bonus").geq(50000))
      .show(false);
    

    This removes the sum of a bonus that is less than 50000 and yields the output below.

    +-----------+----------+-----------------+---------+----------+
    |department |sum_salary|avg_salary       |sum_bonus|max_bonus |
    +-----------+----------+-----------------+---------+----------+
    |Sales      |257000    |85666.66666666667|53000    |23000     |
    |Finance    |351000    |87750.0          |81000    |24000     |
    +-----------+----------+-----------------+---------+----------+
    

    This example is also available in the GitHub project for reference.

    Apache Spark Tutorial with Java Examples — DataFrame Wider Transformation

    Introduction to Apache Spark

    Setup Apache Spark Environment

    SparkSession & SparkContext

    Resilient Distributed Datasets (RDDs)

    Cache, Persistence and Shared Variables

    DataFrame Introduction

    DataFrame Narrow Transformation

    DataFrame Wider Transformation

    DataFrame Actions

    Spark SQL Functions

    Advanced DataFrame Features

    Using SQL Queries

    Spark Read & Write CSV Files

    Working with JSON Files

    Working with Parquet Files

    Spark Dataset

    What Next?

    Tutorial Not Found