agg and sum() after a groupby give one row per group. transform gives the group's answer on every original row, so the result lines up with the table:
df["region_total"] = df.groupby("region")["revenue"].transform("sum")
That makes a family of everyday calculations one line each:
- Share of the group:
df["revenue"] / df.groupby("region")["revenue"].transform("sum")
- Compare with the group:
df[df["revenue"] > df.groupby("category")["revenue"].transform("mean")]
- Fill gaps by group:
col.fillna(df.groupby("type")["col"].transform("median"))
If you see a result with fewer rows than your table, you used an aggregation where you needed transform.