Built with Tutify.io

    AIStudyLabs

    DataFrame - Add & Update Columns

    DataFrame - Add & Update Columns

    Introduction

    Spark withColumn() is a DataFrame function that is used to add a new column to the DataFrame, change the value of an existing column, convert the datatype of a column, or derive a new column from an existing column.

    Spark withColumn() Syntax and Usage

    Spark withColumn() is a transformation function of a DataFrame that is used to manipulate the column values of all rows or selected rows in the DataFrame.

    withColumn() function returns a new Spark DataFrame after performing operations like adding a new column, updating the value of an existing column, deriving a new column from an existing column, and many more.

    Below is the syntax of withColumn() function.

    withColumn(colName : String, col : Column) : DataFrame
    

    colName:String – specify a new column you want to create. Use an existing column to update the value.

    col:Column – column expression.

    Since withColumn() is a transformation function, it doesn’t execute until an action is called.

    Spark withColumn() method introduces a projection internally. Therefore, calling it multiple times, for instance, via loops in order to add multiple columns can generate big plans which can cause performance issues and even StackOverflowException. To avoid this, use select with the multiple columns at once. Spark Documentation

    First, let’s create a DataFrame to work with.

    import org.apache.spark.sql.{Row, SparkSession}
    import org.apache.spark.sql.types.{StringType, StructType}
    
    val data = Seq(
      Row(Row("James", "", "Smith"), "36636", "M", "3000"),
      Row(Row("Michael", "Rose", ""), "40288", "M", "4000"),
      Row(Row("Robert", "", "Williams"), "42114", "M", "4000"),
      Row(Row("Maria", "Anne", "Jones"), "39192", "F", "4000"),
      Row(Row("Jen", "Mary", "Brown"), "", "F", "-1")
    )
    
    val schema = new StructType()
      .add("name", new StructType()
        .add("firstname", StringType)
        .add("middlename", StringType)
        .add("lastname", StringType))
      .add("dob", StringType)
      .add("gender", StringType)
      .add("salary", StringType)
    
    val df = spark.createDataFrame(spark.sparkContext.parallelize(data), schema)
    

    1. Add a New Column to DataFrame

    To create a new column, pass your desired column name to the first argument of withColumn() transformation function. Ensure this new column is not already present on DataFrame; if it is, it updates the value of the column. In the below snippet, the lit() function is used to add a constant value to a DataFrame column. We can also chain in order to add multiple columns.

    // Add a New Column to DataFrame
    import org.apache.spark.sql.functions.lit
    
    df.withColumn("Country", lit("USA"))
    
    // Chaining to operate on multiple columns
    df.withColumn("Country", lit("USA"))
      .withColumn("anotherColumn", lit("anotherValue"))
    

    The above approach is fine if you are manipulating a few columns, but when you want to add or update multiple columns, do not chain withColumn() as it leads to performance issues. Instead, use select() to update multiple columns.

    2. Change Value of an Existing Column

    withColumn() function can also be used to update the value of an existing column. To change the value, pass an existing column name as the first argument and a value to be assigned as a second column. Note that the second argument should be Column type.

    // Change Value of an Existing Column
    import org.apache.spark.sql.functions.col
    
    df.withColumn("salary", col("salary") * 100)
    

    This snippet multiplies the value of “salary” by 100 and updates it back to the “salary” column.

    3. Derive a New Column From an Existing Column

    To create a new column, specify the first argument with a name you want your new column to be and use the second argument to assign a value by applying an operation on an existing column.

    // Derive New Column From an Existing Column
    df.withColumn("CopiedColumn", col("salary") * -1)
    

    This snippet creates a new column, “CopiedColumn,” by multiplying the “salary” column with value -1.

    4. Change Column Data Type

    By using Spark withColumn on a DataFrame and using the cast function on a column, we can change the datatype of a DataFrame column. The below statement changes the datatype from String to Integer for the “salary” column.

    // Change Column Data Type
    df.withColumn("salary", col("salary").cast("Integer"))
    

    5. Split Column into Multiple Columns

    Though this example doesn’t use withColumn() function, it’s still useful to explain splitting one DataFrame column into multiple columns using Spark map() transformation function.

    // Split Column into Multiple Columns
    import spark.implicits._
    
    val columns = Seq("name", "address")
    val data = Seq(
      ("Robert, Smith", "1 Main st, Newark, NJ, 92537"),
      ("Maria, Garcia", "3456 Walnut st, Newark, NJ, 94732")
    )
    
    var dfFromData = spark.createDataFrame(data).toDF(columns: _*)
    dfFromData.printSchema()
    
    val newDF = dfFromData.map(f => {
      val nameSplit = f.getAs[String](0).split(",")
      val addSplit = f.getAs[String](1).split(",")
      (nameSplit(0), nameSplit(1), addSplit(0), addSplit(1), addSplit(2), addSplit(3))
    })
    
    val finalDF = newDF.toDF("First Name", "Last Name", "Address Line1", "City", "State", "zipCode")
    finalDF.printSchema()
    finalDF.show(false)
    

    This snippet splits the name column into “First Name” and “Last Name,” and the address column into “Address Line1,” “City,” “State,” and “ZipCode.”

    The output of the final DataFrame will be:

    root
     |-- First Name: string (nullable = true)
     |-- Last Name: string (nullable = true)
     |-- Address Line1: string (nullable = true)
     |-- City: string (nullable = true)
     |-- State: string (nullable = true)
     |-- zipCode: string (nullable = true)
    
    +----------+---------+--------------+-------+-----+-------+
    |First Name|Last Name|Address Line1 |City   |State|zipCode|
    +----------+---------+--------------+-------+-----+-------+
    |Robert    | Smith   |1 Main st     | Newark| NJ  | 92537 |
    |Maria     | Garcia  |3456 Walnut st| Newark| NJ  | 94732 |
    +----------+---------+--------------+-------+-----+-------+
    

    The complete code can be downloaded from GitHub

    Apache Spark Tutorial with Scala Examples — DataFrame Narrow Transformation

    Introduction to Apache Spark

    Setup Apache Spark Environment

    SparkSession & SparkContext

    Resilient Distributed Datasets (RDDs)

    Apache Spark Concepts

    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