Skip to content

fenic.api.dataframe.grouped_data

GroupedData class for aggregations on grouped DataFrames.

Classes:

  • GroupedData

    Methods for aggregations on a grouped DataFrame.

GroupedData

GroupedData(df: DataFrame, by: Optional[List[ColumnOrName]] = None)

Bases: BaseGroupedData

Methods for aggregations on a grouped DataFrame.

Initialize grouped data.

Parameters:

  • df (DataFrame) –

    The DataFrame to group.

  • by (Optional[List[ColumnOrName]], default: None ) –

    Optional list of columns to group by.

Methods:

  • agg

    Compute aggregations on grouped data and return the result as a DataFrame.

Source code in src/fenic/api/dataframe/grouped_data.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(self, df: DataFrame, by: Optional[List[ColumnOrName]] = None):
    """Initialize grouped data.

    Args:
        df: The DataFrame to group.
        by: Optional list of columns to group by.
    """
    super().__init__(df)
    self._by: List[Column] = []
    for c in by or []:
        if isinstance(c, str):
            self._by.append(col(c))
        elif isinstance(c, Column):
            # Allow any expression except literals
            if isinstance(c._logical_expr, LiteralExpr):
                raise ValueError(f"Cannot group by literal value: {c}")
            self._by.append(c)
        else:
            raise TypeError(
                f"Group by expressions must be string or Column, got {type(c)}"
            )
    self._by_exprs = [c._logical_expr for c in self._by]

agg

agg(*exprs: Union[Column, Dict[str, str]]) -> DataFrame

Compute aggregations on grouped data and return the result as a DataFrame.

This method applies aggregate functions to the grouped data.

Parameters:

  • *exprs (Union[Column, Dict[str, str]], default: () ) –

    Aggregation expressions. Can be:

    • Column expressions with aggregate functions (e.g., count("*"), sum("amount"))
    • A dictionary mapping column names to aggregate function names (e.g., {"amount": "sum", "age": "avg"})

Returns:

  • DataFrame ( DataFrame ) –

    A new DataFrame with one row per group and columns for group keys and aggregated values

Raises:

  • ValueError

    If arguments are not Column expressions or a dictionary

  • ValueError

    If dictionary values are not valid aggregate function names

Count employees by department
# Group by department and count employees
df.group_by("department").agg(count("*").alias("employee_count"))
Multiple aggregations
# Multiple aggregations
df.group_by("department").agg(
    count("*").alias("employee_count"),
    avg("salary").alias("avg_salary"),
    max("age").alias("max_age")
)
Dictionary style aggregations
# Dictionary style for simple aggregations
df.group_by("department", "location").agg({"salary": "avg", "age": "max"})
Source code in src/fenic/api/dataframe/grouped_data.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def agg(self, *exprs: Union[Column, Dict[str, str]]) -> DataFrame:
    """Compute aggregations on grouped data and return the result as a DataFrame.

    This method applies aggregate functions to the grouped data.

    Args:
        *exprs: Aggregation expressions. Can be:

            - Column expressions with aggregate functions (e.g., `count("*")`, `sum("amount")`)
            - A dictionary mapping column names to aggregate function names (e.g., `{"amount": "sum", "age": "avg"}`)

    Returns:
        DataFrame: A new DataFrame with one row per group and columns for group keys and aggregated values

    Raises:
        ValueError: If arguments are not Column expressions or a dictionary
        ValueError: If dictionary values are not valid aggregate function names

    Example: Count employees by department
        ```python
        # Group by department and count employees
        df.group_by("department").agg(count("*").alias("employee_count"))
        ```

    Example: Multiple aggregations
        ```python
        # Multiple aggregations
        df.group_by("department").agg(
            count("*").alias("employee_count"),
            avg("salary").alias("avg_salary"),
            max("age").alias("max_age")
        )
        ```

    Example: Dictionary style aggregations
        ```python
        # Dictionary style for simple aggregations
        df.group_by("department", "location").agg({"salary": "avg", "age": "max"})
        ```
    """
    self._validate_agg_exprs(*exprs)
    if len(exprs) == 1 and isinstance(exprs[0], dict):
        agg_dict = exprs[0]
        return self.agg(*self._process_agg_dict(agg_dict))

    agg_exprs = self._process_agg_exprs(exprs)
    return self._df._from_logical_plan(
        Aggregate(self._df._logical_plan, self._by_exprs, agg_exprs),
    )