Built with Tutify.io

    AIStudyLabs

    Extract First and last N rows from PySpark DataFrame

    Extract First and last N rows from PySpark DataFrame

    In PySpark, extracting the first or last N rows from a DataFrame is a common requirement in data analysis and ETL pipelines. PySpark provides multiple ways to achieve this, either by using built-in DataFrame functions like limit(), head(), and tail(), or by applying window functions with row_number() when working with grouped or partitioned data.

    The approach you choose depends on whether you need rows from the entire DataFrame or from each group within the DataFrame.

    In this article, we’ll explore:

    Key Points-

    <a id="h-create-a-sample-dataframe"></a>

    Create a Sample DataFrame

    Let's create a sample DataFrame.

    
    from pyspark.sql import SparkSession
    spark = SparkSession.builder.appName("app").getOrCreate()
    
    data = [
        ("James","Sales",3000),
        ("Michael","Sales",4600),
        ("Robert","Sales",4100),
        ("Maria","Finance",3000),
        ("Raman","Finance",3000),
        ("Scott","Finance",3300),
        ("Jen","Finance",3900),
        ("Jeff","Marketing",3000),
        ("Kumar","Marketing",2000)
    ]
    
    cols = ["Name","Department","Salary"]
    df = spark.createDataFrame(data, cols)
    df.show()
    

    Extracting First N Rows

    When working with large datasets, it’s often useful to take a quick look at the first few rows to understand the structure and content of the data. PySpark offers several ways to extract the first N rows, which we’ll explore below.

    Using head()

    The head() method retrieves the first N rows of a DataFrame. It returns a list of Row objects, allowing you to access the data as a regular Python list.

    
    # extract top 2 rows
    a = df.head(2)
    print(a)
    
    # extract top 1 row
    a = df.head(1)
    print(a)
    

    Yields below output.

    <a id="h-using-first"></a>

    Using first()

    The first() method retrieves only the very first row from the DataFrame. It’s similar to head(1) but returns a single Row object instead of a list.

    
    # Return first row of DataFrame
    a = df.first()
    print(a)
    
    # Output:
    # Row(Name='James', Department='Sales', Salary=3000)
    

    <a id="h-using-limit-n-collect"></a>

    Using limit(n).collect()

    The limit(n) function restricts the number of rows, and collect() converts them into a list of Row objects.

    
    # Use limit() and collect() to return limited number of rows 
    a = df.limit(3).collect()
    print(a)
    
    # Output:
    # [Row(Name='James', Department='Sales', Salary=3000), Row(Name='Michael', Department='Sales', Salary=4600), # Row(Name='Robert', Department='Sales', Salary=4100)]
    

    <a id="h-extract-top-n-rows-per-group"></a>

    Extract Top N Rows Per Group

    In real-world datasets, we often need to extract the top N rows for each group based on a specific column.
    We can achieve this using Window.partitionBy() along with the row_number() function.

    For example, let’s get the top 2 employees per Department by Salary.

    
    # Extracting Top N Rows Per Group
    from pyspark.sql.window import Window
    from pyspark.sql.functions import row_number, col
    
    # Define window partitioned by Department and ordered by Salary (descending)
    windowSpec = Window.partitionBy("Department").orderBy(col("Salary").desc())
    
    # Add row_number column
    df_topN = df.withColumn("row_num", row_number().over(windowSpec)) \
                .filter(col("row_num") <= 2) \
                .drop("row_num")
    
    df_topN.show()
    
    # Output:
    # +-------+----------+------+
    # |   Name|Department|Salary|
    # +-------+----------+------+
    # |    Jen|   Finance|  3900|
    # |  Scott|   Finance|  3300|
    # |   Jeff| Marketing|  3000|
    # |  Kumar| Marketing|  2000|
    # |Michael|     Sales|  4600|
    # | Robert|     Sales|  4100|
    # +-------+----------+------+
    

    <a id="h-extract-last-n-rows"></a>

    Extract Last N Rows

    When working with large datasets, it is often useful to quickly inspect the last few rows to gain insights into the most recent entries or the tail end of the data. We can extract the last N rows using the following methods.

    Using tail()

    The tail() method fetches the last N rows from the DataFrame, returning a list of Row objects similar to head(), but from the end.

    
    # Use tail() to get last n rows
    df.tail(3)
    
    # Output:
    [Row(Name='Jen', Department='Finance', Salary=3900),
     Row(Name='Jeff', Department='Marketing', Salary=3000),
     Row(Name='Kumar', Department='Marketing', Salary=2000)]
    

    <a id="h-using-collect"></a>

    Using collect()

    You can also use the collect() method to retrieve all rows from the DataFrame as a list of Rows, and then slice it to get the last N rows.

    
    # Retrieve all columns using collect()
    df.collect()[-3:]
    
    # Output:
    [Row(Name='Jen', Department='Finance', Salary=3900),
     Row(Name='Jeff', Department='Marketing', Salary=3000),
     Row(Name='Kumar', Department='Marketing', Salary=2000)]
    

    <a id="h-extracting-last-n-rows-per-group"></a>

    Extracting Last N Rows Per Group

    Similarly, to get the last N rows per group, we just need to order the window in ascending order instead of descending.

    
    # Define window partitioned by Department and ordered by Salary (ascending)
    windowSpecAsc = Window.partitionBy("Department").orderBy(col("Salary").asc())
    
    # Add row_number column
    df_lastN = df.withColumn("row_num", row_number().over(windowSpecAsc)) \
                 .filter(col("row_num") <= 2) \
                 .drop("row_num")
    
    df_lastN.show()
    
    # Output:
    # +------+----------+------+
    # |  Name|Department|Salary|
    # +------+----------+------+
    # | Maria|   Finance|  3000|
    # | Raman|   Finance|  3000|
    # | Kumar| Marketing|  2000|
    # |  Jeff| Marketing|  3000|
    # | James|     Sales|  3000|
    # |Robert|     Sales|  4100|
    # +------+----------+------+
    

    <a id="h-frequently-asked-questions-faqs"></a>

    Frequently Asked Questions (FAQs)

    first() returns a single Row object.

    Use tail(n) instead of collect().

    Use rank() or dense_rank() instead of row_number().

    <a id="h-conclusion"></a>

    Conclusion

    In this article, I have explained different ways to extract the first and last N rows from a PySpark DataFrame, both from the entire dataset and within groups.

    By combining these approaches, you can easily retrieve the top or bottom N rows for any analytical or reporting requirement in PySpark.

    Happy Learning!!

    <a id="h-related-articles"></a>

    Related Articles