Explain Codes LogoExplain Codes Logo

Return multiple columns from pandas apply()

python
pandas
apply
performance
Anton ShumikhinbyAnton Shumikhin·Mar 5, 2025
TLDR

To output multiple columns using apply() in Pandas, create a function returning a pd.Series and set index as new column names:

import pandas as pd df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}) result = df.apply(lambda x: pd.Series({'Sum': x['A'] + x['B'], 'Product': x['A'] * x['B']}), axis=1) print(result)

Output:

   Sum  Product
0    4        3
1    6        8

Effortlessly incorporate Sum and Product columns into df achieving a comprehensive DataFrame.

Boosting efficiency with tuples

Fancy making your code run 3x faster? Make a small tweak by returning a tuple instead of a Series from the apply() function. Here, we perform two computation operations simultaneously.

def compute_metrics(row): return (row['A'] + row['B'], row['A'] * row['B']) result = df.apply(lambda x: compute_metrics(x), axis=1, result_type='expand') df[['Sum', 'Product']] = result print(df)

Output:

   A  B  Sum  Product
0  1  3    4        3
1  2  4    6        8

Cracking the result_type='expand' code

When your apply() function produces a list-like result, use the result_type='expand' parameter to separate the result into individual DataFrame columns like a boss:

result = df.apply(lambda x: [x['A'] + x['B'], x['A'] * x['B']], axis=1, result_type='expand') df[['Sum', 'Product']] = result

The power couple: zip() and apply()

What if I told you that you could make your code run even faster without typing result_type='expand'? The old zip() function can be your apply() function's partner-in-crime in achieving this:

df['Sum'], df['Product'] = zip(*df.apply(lambda x: (x['A'] + x['B'], x['A'] * x['B']), axis=1))

Cosmetic touches with locale.format()

Let's turn those raw numbers into consistent, neat data using the locale.format() function. Just as we place great importance on ease of understanding, don't underestimate the power of ease of reading:

import locale locale.setlocale(locale.LC_ALL, '') df['SumFormatted'], df['ProductFormatted'] = zip(*df.apply( lambda x: ( locale.format_string('%f', x['Sum']), locale.format_string('%f', x['Product']) ), axis=1 ))

Saving precious time with one-pass calculations

Teach your apply() function to multitask by conducting multiple calculations in one go. Say goodbye to separate apply() functions that incur additional overhead!

Serve directly to new DataFrame columns

Serve the results from your apply() function directly to new DataFrame columns. This "direct-to-table" service strips away the extra fat and serves up your data quicker:

df['A_squared'], df['B_squared'] = zip(*df.apply(lambda x: (x['A']**2, x['B']**2), axis=1)) #Speed is the secret sauce here!🚀

Read the room (or, the version)

Performances may vary across versions of Pandas. Be sure to tune your code to match the frequency of your current pandas version 0.23 or later for optimal results.

Make it a la GroupBy

Up your DataFrame's readability up a notch by grouping related operations together within your apply() function. Result? A neatly served dish of data!