GroupBy
GroupBy Count
Tally how many rows fall into each category by looping over a category list
and incrementing a per-key counter. With pandas, df.groupby('cat').size()
performs the same split-and-count in one call and returns a Series indexed by
the category labels.
By hand
Loop over cats, incrementing counts[cat] for each occurrence using
.get(cat, 0) to handle first-time keys. Sort the keys for a stable result.
naive.py
Replay: real traced execution (multi-file project)
cats = ['a', 'b', 'a', 'c', 'b', 'a']
counts = {}
for cat in cats:
counts[cat] = counts.get(cat, 0) + 1
result = {k: counts[k] for k in sorted(counts)}
print('RESULT:', result)
cats ← ['a', 'b', 'a', 'c', 'b', 'a']
1cats = ['a', 'b', 'a', 'c', 'b', 'a']2counts = {}values this step['a', 'b', 'a', 'c', 'b', 'a']catscounts ← {}
1cats = ['a', 'b', 'a', 'c', 'b', 'a']2counts = {}3for cat in cats:values this step{}countscat ← 'a'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'a'catcounts ← {'a': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{} → {'a': 1}countscat ← 'b'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'a' → 'b'catcounts ← {'a': 1, 'b': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{'a': 1} → {'a': 1, 'b': 1}countscat ← 'a'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'b' → 'a'catcounts ← {'a': 2, 'b': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{'a': 1, 'b': 1} → {'a': 2, 'b': 1}countscat ← 'c'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'a' → 'c'catcounts ← {'a': 2, 'b': 1, 'c': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{'a': 2, 'b': 1} → {'a': 2, 'b': 1, 'c': 1}countscat ← 'b'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'c' → 'b'catcounts ← {'a': 2, 'b': 2, 'c': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{'a': 2, 'b': 1, 'c': 1} → {'a': 2, 'b': 2, 'c': 1}countscat ← 'a'
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1values this step'b' → 'a'catcounts ← {'a': 3, 'b': 2, 'c': 1}
3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}values this step{'a': 2, 'b': 2, 'c': 1} → {'a': 3, 'b': 2, 'c': 1}countsfor cat in cats:
2counts = {}3for cat in cats:4 counts[cat] = counts.get(cat, 0) + 1result ← {'a': 3, 'b': 2, 'c': 1}
4 counts[cat] = counts.get(cat, 0) + 15result = {k: counts[k] for k in sorted(counts)}6print('RESULT:', result)values this step{'a': 3, 'b': 2, 'c': 1}resultstdout ← RESULT: {'a': 3, 'b': 2, 'c': 1}
5result = {k: counts[k] for k in sorted(counts)}6print('RESULT:', result)values this stepRESULT: {'a': 3, 'b': 2, 'c': 1}stdout
With pandas
df.groupby('cat').size() groups the rows by category and returns the row
count per group as a Series. int() converts numpy scalars for a stable
result dict.
library.py
import pandas as pd
from dalib.display import set_display
set_display()
cats = ['a', 'b', 'a', 'c', 'b', 'a']
df = pd.DataFrame({'cat': cats})
counts = df.groupby('cat').size()
result = {k: int(counts[k]) for k in sorted(counts.index)}
print('index:', sorted(counts.index.tolist()))
print('values:', [int(counts[k]) for k in sorted(counts.index)])
print('dtype:', counts.dtype)
print('RESULT:', result)
index: ['a', 'b', 'c']
values: [3, 2, 1]
dtype: int64
RESULT: {'a': 3, 'b': 2, 'c': 1}
Implementation notes
groupby('cat').size()counts all rows per group, including rows with NaN in other columns. Use.count()instead to count non-null values in a specific column:df.groupby('cat')['val'].count().- The result Series is indexed by the group keys in sorted order (pandas sorts group keys by default). This matches the sorted-key dict produced in the naive half.
- Cross-reference:
group-count(python-data-basics) for the pure-Python counter version.