Facebook Pixel

2879. Display the First Three Rows

Problem Description

You are given a DataFrame called employees that contains information about company employees. The DataFrame has the following structure:

  • employee_id (int): A unique identifier for each employee
  • name (object): The employee's name
  • department (object): The department where the employee works
  • salary (int): The employee's salary

Your task is to write a function that returns the first 3 rows of this DataFrame.

The solution uses pandas' built-in head() method, which is designed to retrieve the first n rows from a DataFrame. By calling employees.head(3), the function returns a new DataFrame containing only the first 3 rows of the original employees DataFrame, preserving all columns and their values.

This is a fundamental pandas operation commonly used for quickly inspecting the beginning of a dataset or limiting the output to a specific number of top rows.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

When we need to select a specific number of rows from the beginning of a DataFrame, the most straightforward approach is to use pandas' built-in methods rather than manual indexing or slicing.

The key insight is recognizing that this is a common operation in data analysis - viewing the first few rows of a dataset to understand its structure and content. Pandas provides the head() method specifically for this purpose.

Why head(3) over other approaches like employees[:3] or employees.iloc[:3]? While these alternatives would also work, head() is:

  • More readable and self-documenting - it clearly expresses the intent to get the "head" of the data
  • Safer when dealing with DataFrames that might have fewer rows than requested (it returns all available rows without throwing an error)
  • The conventional pandas way to perform this operation

The solution is elegant in its simplicity - we don't need loops, conditional logic, or complex indexing. We leverage the fact that pandas has already solved this common use case with a dedicated method that handles edge cases gracefully.

Solution Approach

The implementation is straightforward and consists of a single function call:

def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
    return employees.head(3)

Let's break down the implementation:

  1. Function Definition: The function selectFirstRows takes one parameter:

    • employees: A pandas DataFrame containing employee data
    • The function returns a pandas DataFrame (the first 3 rows)
  2. Core Operation: The solution uses the head() method:

    • employees.head(3) retrieves the first 3 rows from the DataFrame
    • This method creates a new DataFrame containing only these rows
    • All columns (employee_id, name, department, salary) are preserved
    • The original DataFrame remains unchanged
  3. Method Behavior:

    • If the DataFrame has 3 or more rows, it returns exactly 3 rows
    • If the DataFrame has fewer than 3 rows (e.g., only 2 rows), it returns all available rows without error
    • If the DataFrame is empty, it returns an empty DataFrame

The beauty of this solution lies in its use of pandas' optimized internal implementation. The head() method efficiently accesses the first n rows without needing to iterate through the entire DataFrame, making it performant even for large datasets.

No additional data structures or complex algorithms are needed - we simply leverage pandas' built-in functionality to achieve the desired result in a single, clean line of code.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example to understand how the solution works.

Suppose we have the following employees DataFrame:

employee_idnamedepartmentsalary
101AliceSales75000
102BobIT85000
103CharlieHR65000
104DianaSales72000
105EveIT90000

When we call selectFirstRows(employees), the function executes employees.head(3).

Step-by-step execution:

  1. The head(3) method is invoked on the DataFrame
  2. Pandas internally accesses the first 3 rows based on the DataFrame's index
  3. A new DataFrame is created containing only these rows
  4. All column information is preserved

Result:

employee_idnamedepartmentsalary
101AliceSales75000
102BobIT85000
103CharlieHR65000

The function returns this new DataFrame with exactly 3 rows, maintaining the original column structure and data types.

Edge Case Example:

If the DataFrame only had 2 employees:

employee_idnamedepartmentsalary
101AliceSales75000
102BobIT85000

Calling employees.head(3) would return all 2 available rows without any errors, demonstrating the method's graceful handling of edge cases where fewer rows exist than requested.

Solution Implementation

1import pandas as pd
2
3
4def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
5    """
6    Select and return the first 3 rows from the employees DataFrame.
7  
8    Args:
9        employees: A pandas DataFrame containing employee data
10      
11    Returns:
12        A pandas DataFrame containing only the first 3 rows
13    """
14    # Use the head() method to get the first 3 rows of the DataFrame
15    return employees.head(3)
16
1import java.util.List;
2import java.util.ArrayList;
3import java.util.Map;
4
5public class Solution {
6    /**
7     * Select and return the first 3 rows from the employees DataFrame.
8     * 
9     * @param employees A List of Maps representing employee data (similar to DataFrame rows)
10     * @return A List containing only the first 3 rows
11     */
12    public List<Map<String, Object>> selectFirstRows(List<Map<String, Object>> employees) {
13        // Check if the input is null or empty
14        if (employees == null || employees.isEmpty()) {
15            return new ArrayList<>();
16        }
17      
18        // Determine how many rows to return (minimum of 3 or the size of the list)
19        int rowsToReturn = Math.min(3, employees.size());
20      
21        // Use subList to get the first 3 rows (equivalent to pandas head(3))
22        // subList returns a view, so we create a new ArrayList to return a copy
23        return new ArrayList<>(employees.subList(0, rowsToReturn));
24    }
25}
26
1#include <vector>
2#include <unordered_map>
3#include <string>
4#include <algorithm>
5
6// Define a structure to represent a DataFrame-like container
7struct DataFrame {
8    std::vector<std::string> columns;                           // Column names
9    std::vector<std::vector<std::string>> data;                // Row data stored as strings
10  
11    // Constructor
12    DataFrame() = default;
13  
14    // Get the number of rows in the DataFrame
15    size_t size() const {
16        return data.size();
17    }
18};
19
20/**
21 * Select and return the first 3 rows from the employees DataFrame.
22 * 
23 * @param employees A DataFrame containing employee data
24 * @return A DataFrame containing only the first 3 rows
25 */
26DataFrame selectFirstRows(const DataFrame& employees) {
27    DataFrame result;
28  
29    // Copy column names to the result DataFrame
30    result.columns = employees.columns;
31  
32    // Calculate the number of rows to copy (minimum of 3 or total rows available)
33    size_t rows_to_copy = std::min(static_cast<size_t>(3), employees.size());
34  
35    // Copy the first 'rows_to_copy' rows from the input DataFrame
36    for (size_t i = 0; i < rows_to_copy; ++i) {
37        result.data.push_back(employees.data[i]);
38    }
39  
40    return result;
41}
42
1// Import statement would be handled differently in TypeScript
2// TypeScript doesn't have pandas, but we'll represent the structure
3
4interface DataFrame {
5    head(n: number): DataFrame;
6    // Other DataFrame methods would be defined here
7}
8
9/**
10 * Select and return the first 3 rows from the employees DataFrame.
11 * 
12 * @param employees - A DataFrame containing employee data
13 * @returns A DataFrame containing only the first 3 rows
14 */
15function selectFirstRows(employees: DataFrame): DataFrame {
16    // Use the head() method to get the first 3 rows of the DataFrame
17    return employees.head(3);
18}
19

Time and Space Complexity

Time Complexity: O(1) or O(k) where k = 3

The head(3) operation in pandas retrieves the first 3 rows from the DataFrame. Since we're accessing a fixed number of rows (3), this operation takes constant time regardless of the total size of the DataFrame. The implementation typically involves slicing the underlying data structure, which for a fixed slice size is a constant-time operation.

Space Complexity: O(1) or O(k) where k = 3

The space complexity is also constant because:

  • The head(3) method returns a view or a copy of only 3 rows from the original DataFrame
  • The amount of memory used for the output is proportional to the number of rows returned (3) and the number of columns, but since we're always returning exactly 3 rows, this is considered constant space
  • No additional data structures are created that scale with the input size
  • The original DataFrame is not modified, and only a reference to the first 3 rows is returned

Note: While the space used technically depends on the number of columns in the DataFrame, since the column count is not changing and we're only considering row operations, the space complexity with respect to the number of rows in the input is O(1).

Common Pitfalls

1. Assuming the DataFrame Always Has 3 Rows

A common misconception is that head(3) will always return exactly 3 rows. If the DataFrame has fewer than 3 rows, head(3) will return all available rows without raising an error.

Example:

# DataFrame with only 2 rows
df = pd.DataFrame({'employee_id': [1, 2], 'name': ['Alice', 'Bob']})
result = df.head(3)  # Returns 2 rows, not 3

Solution: If you need to ensure exactly 3 rows (padding with NaN if necessary), you could use:

def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
    result = employees.head(3)
    if len(result) < 3:
        # Optionally handle the case where fewer than 3 rows exist
        # Could pad with NaN rows or raise a warning
        pass
    return result

2. Modifying the Returned DataFrame Thinking It's a Copy

While head() returns a new DataFrame object, it creates a view that shares the underlying data with the original DataFrame. Modifying values in the returned DataFrame might trigger a SettingWithCopyWarning.

Example:

first_three = employees.head(3)
first_three['salary'] = 100000  # May trigger SettingWithCopyWarning

Solution: If you need to modify the returned data, explicitly create a copy:

def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
    return employees.head(3).copy()

3. Not Handling Empty DataFrames

When the input DataFrame is empty, head(3) returns an empty DataFrame, which might not be the expected behavior in all contexts.

Example:

empty_df = pd.DataFrame()
result = empty_df.head(3)  # Returns empty DataFrame with no rows or columns

Solution: Add validation if empty DataFrames need special handling:

def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
    if employees.empty:
        # Handle empty DataFrame case
        # Could return a default DataFrame or raise an exception
        return pd.DataFrame(columns=['employee_id', 'name', 'department', 'salary'])
    return employees.head(3)

4. Confusing head() with Index-Based Selection

head(3) returns the first 3 rows based on the DataFrame's current order, not based on index values. If the DataFrame has a non-sequential index, this might cause confusion.

Example:

# DataFrame with custom index
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie']}, index=[5, 10, 15])
df.head(2)  # Returns rows with index 5 and 10, not rows with index 0 and 1

Solution: If you need specific index values, use iloc or loc:

def selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:
    # If you need rows at positions 0, 1, 2 regardless of index
    return employees.iloc[:3]
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What's the output of running the following function using input [30, 20, 10, 100, 33, 12]?

1def fun(arr: List[int]) -> List[int]:
2    import heapq
3    heapq.heapify(arr)
4    res = []
5    for i in range(3):
6        res.append(heapq.heappop(arr))
7    return res
8
1public static int[] fun(int[] arr) {
2    int[] res = new int[3];
3    PriorityQueue<Integer> heap = new PriorityQueue<>();
4    for (int i = 0; i < arr.length; i++) {
5        heap.add(arr[i]);
6    }
7    for (int i = 0; i < 3; i++) {
8        res[i] = heap.poll();
9    }
10    return res;
11}
12
1class HeapItem {
2    constructor(item, priority = item) {
3        this.item = item;
4        this.priority = priority;
5    }
6}
7
8class MinHeap {
9    constructor() {
10        this.heap = [];
11    }
12
13    push(node) {
14        // insert the new node at the end of the heap array
15        this.heap.push(node);
16        // find the correct position for the new node
17        this.bubble_up();
18    }
19
20    bubble_up() {
21        let index = this.heap.length - 1;
22
23        while (index > 0) {
24            const element = this.heap[index];
25            const parentIndex = Math.floor((index - 1) / 2);
26            const parent = this.heap[parentIndex];
27
28            if (parent.priority <= element.priority) break;
29            // if the parent is bigger than the child then swap the parent and child
30            this.heap[index] = parent;
31            this.heap[parentIndex] = element;
32            index = parentIndex;
33        }
34    }
35
36    pop() {
37        const min = this.heap[0];
38        this.heap[0] = this.heap[this.size() - 1];
39        this.heap.pop();
40        this.bubble_down();
41        return min;
42    }
43
44    bubble_down() {
45        let index = 0;
46        let min = index;
47        const n = this.heap.length;
48
49        while (index < n) {
50            const left = 2 * index + 1;
51            const right = left + 1;
52
53            if (left < n && this.heap[left].priority < this.heap[min].priority) {
54                min = left;
55            }
56            if (right < n && this.heap[right].priority < this.heap[min].priority) {
57                min = right;
58            }
59            if (min === index) break;
60            [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61            index = min;
62        }
63    }
64
65    peek() {
66        return this.heap[0];
67    }
68
69    size() {
70        return this.heap.length;
71    }
72}
73
74function fun(arr) {
75    const heap = new MinHeap();
76    for (const x of arr) {
77        heap.push(new HeapItem(x));
78    }
79    const res = [];
80    for (let i = 0; i < 3; i++) {
81        res.push(heap.pop().item);
82    }
83    return res;
84}
85

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More