Skip to content
Back to skills

Declarative Groupby Aggregation

ASecurity

Config-driven feature factory that generates groupby aggregation features from a declarative spec list, supporting count, mean, var, nunique, cumcount, and custom lambdas.

  • 61 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 12, 2026
datapythontesting

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill declarative-groupby-aggregation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Declarative Groupby Aggregation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Declarative Groupby Aggregation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-declarative-groupby-aggregation/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-declarative-groupby-aggregation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tabular-declarative-groupby-aggregation
description: >
  Config-driven feature factory that generates groupby aggregation features from a declarative spec list, supporting count, mean, var, nunique, cumcount, and custom lambdas.
---
# Declarative GroupBy Aggregation

## Overview

Feature engineering in tabular competitions often requires dozens of groupby aggregations (count by IP, nunique apps per device, variance of channel per OS, etc.). Instead of writing each one manually, define a spec list of `{groupby, select, agg}` dictionaries and loop through them. This pattern is self-documenting, easy to extend, and reduces copy-paste bugs. Used extensively in fraud detection, recommendation, and any multi-entity dataset.

## Quick Start

```python
import pandas as pd
import numpy as np
import gc

GROUPBY_AGGREGATIONS = [
    {'groupby': ['ip'], 'select': 'app', 'agg': 'nunique'},
    {'groupby': ['ip', 'app'], 'select': 'channel', 'agg': 'count'},
    {'groupby': ['ip', 'device', 'os'], 'select': 'app', 'agg': 'cumcount'},
    {'groupby': ['ip'], 'select': 'channel', 'agg': 'var'},
    {'groupby': ['ip', 'app', 'os'], 'select': 'hour', 'agg': 'mean'},
    {'groupby': ['ip'], 'select': 'app', 'agg': lambda x: x.value_counts().head(1).index[0],
     'agg_name': 'mode'},
]

for spec in GROUPBY_AGGREGATIONS:
    agg_name = spec.get('agg_name', spec['agg'].__name__
                        if callable(spec['agg']) else spec['agg'])
    new_feature = '{}_{}_{}'.format('_'.join(spec['groupby']),
                                    agg_name, spec['select'])
    cols = list(set(spec['groupby'] + [spec['select']]))
    gp = df[cols].groupby(spec['groupby'])[spec['select']] \
        .agg(spec['agg']).reset_index() \
        .rename(columns={spec['select']: new_feature})

    if spec['agg'] == 'cumcount':
        df[new_feature] = gp[0].values
    else:
        df = df.merge(gp, on=spec['groupby'], how='left')
    del gp; gc.collect()
```

## Workflow

1. Define a list of spec dicts: `groupby` keys, `select` column, `agg` function
2. Loop through specs, computing each aggregation
3. Merge result back to main DataFrame (or assign directly for cumcount)
4. Delete intermediates and gc.collect() to manage memory

## Key Decisions

- **Naming convention**: Auto-generate feature names from spec for traceability
- **cumcount vs merge**: cumcount produces a per-row sequence number — assign directly, don't merge
- **Memory**: Delete groupby results after merge; process specs in order of memory impact
- **Custom aggs**: Use `agg_name` key for lambdas since `__name__` defaults to `<lambda>`

## References

- [Feature Engineering & Importance Testing](https://www.kaggle.com/code/nanomathias/feature-engineering-importance-testing)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.