How to group dataframe rows into list in pandas groupby
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Pandas groupby splits a DataFrame into groups based on one or more columns, then applies an aggregation function to each group. The default aggregations — sum, mean, count — collapse each group into a single scalar. But sometimes you need to collect all values in a group into a list rather than reducing them. This is useful for building lookup tables, generating comma-separated summaries, or feeding grouped data into machine learning pipelines.
Basic: Collect Column Values into Lists
Use .apply(list) or .agg(list) on a grouped column:
Both .apply(list) and .agg(list) produce the same result. .agg(list) is slightly faster because it avoids the overhead of apply.
Multiple Columns into Lists
To collect multiple columns into lists simultaneously, use .agg(list) on the entire grouped DataFrame:
Mixed Aggregations: Lists and Scalars
Use .agg() with a dictionary to apply different functions to different columns:
This named aggregation syntax (pandas 0.25+) is the cleanest way to mix list collection with scalar aggregations.
Collect Unique Values or Sorted Lists
Convert Lists to Strings
A common follow-up is joining list values into comma-separated strings:
Group by Multiple Columns
Performance: apply(list) vs agg(list)
For large DataFrames, .agg(list) is generally faster than .apply(list) because agg is optimized internally:
For very large datasets where you do not need actual Python lists, consider using tuple instead of list (tuples are slightly more memory-efficient) or restructuring your workflow to avoid collecting into lists altogether.
Common Pitfalls
- Lists in DataFrame cells are hard to query: Once values are collected into lists, filtering and joining become awkward. Consider whether a MultiIndex or a separate lookup table is a better design.
.apply(list)returns a Series, not a DataFrame: If you need a DataFrame, chain.reset_index()or use.agg(list)on the full group.- Memory with large groups: Collecting millions of values into lists can consume significant memory. If each group is very large, consider sampling or using generators instead.
- Column name conflicts with named agg: In named aggregation (
agg(col_name=('col', func))), the output column name cannot match an existing groupby key name. Rename if needed. - Non-hashable groupby keys: If the groupby column itself contains lists or dicts,
groupbywill fail. Convert to tuples or strings first.
Summary
- Use
df.groupby('col')['val'].agg(list)to collect values into lists (fastest) - Use
.apply(list)as an equivalent alternative with slightly more overhead - Use named aggregation
agg(name=('col', list))to mix list collection with scalar aggregations like sum or count - Chain
.reset_index()to convert the grouped result back into a flat DataFrame - For string concatenation, use
.apply(', '.join)instead of collecting into lists
Related reading
- How to handle a situation of feature scaling in machine learning model deployment when you have only one testing instance?
- How to handle categorical variables in sklearn GradientBoostingClassifier?
- How to handle missing NaNs for machine learning in python
- How to handle Shift in Forecasted value
- How to Guarantee Message delivery with Celery?
- How to handle connection issues with kafka using the python kafka library?
- How to handle unseen categorical values in test data set using python?
- How to have one colorbar for all subplots
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.