I suspect what you are looking for is the new df.expanding(..., method='table') in the upcoming pandas=1.3 (see "Other enhancements").

In the meantime, you can do it "by hand", using a loop (sorry):

xy = df.values
df['c1 c2 c3'.split()] = np.stack([
    func2(*xy[:n].T) if n >= 3 else np.empty(3)*np.nan
    for n in range(xy.shape[0])
])

Example:

np.random.seed(0)
df = pd.DataFrame(np.random.rand(10, 2).round(2), 
                  columns=['Input', 'Response'])

# the code above, then

>>> df
   Input  Response         c1         c2        c3
0   0.55      0.72        NaN        NaN       NaN
1   0.60      0.54        NaN        NaN       NaN
2   0.42      0.65        NaN        NaN       NaN
3   0.44      0.89 -22.991453  22.840171 -4.887179
4   0.96      0.38 -29.759096  29.213620 -6.298277
5   0.79      0.53   0.454036  -1.369701  1.272156
6   0.57      0.93   0.122450  -0.874260  1.113586
7   0.07      0.09  -1.010312   0.623331  0.696287
8   0.02      0.83  -2.687387   2.995143 -0.079214
9   0.78      0.87  -1.425030   1.294210  0.442684
Answer from Pierre D on Stack Overflow
🌐
Stack Overflow
stackoverflow.com › questions › 72366016 › how-can-i-use-multiple-columns-of-pandas-expanding-separately-when-applying-fu
python - How can I use multiple columns of Pandas expanding() separately when applying functions with multiple args? - Stack Overflow
It is not yet fully implemented in pandas but there are things you can do to workaround. expanding() and rolling() plus .agg() or .apply() will deal column by column unless you precise method='table', (see Method 2).
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.DataFrame.apply.html
pandas.DataFrame.apply — pandas 3.0.1 documentation
However if the apply function returns a Series these are expanded to columns. ... Positional arguments to pass to func in addition to the array/series. ... Only has an effect when func is a listlike or dictlike of funcs and the func isn’t a string. If “compat”, will if possible first translate the func into pandas ...
Discussions

python - Pandas' expanding with apply function on multiple columns - Stack Overflow
Is it possible to use panda's expanding function to calculate the coefficient of a polynomial regression using several columns of the window object? I have a data frame which has two columns, a pre... More on stackoverflow.com
🌐 stackoverflow.com
python - Apply pandas function to column to create multiple new columns? - Stack Overflow
How to do this in pandas: I have a function extract_text_features on a single text column, returning multiple output columns. Specifically, the function returns 6 values. The function works, however More on stackoverflow.com
🌐 stackoverflow.com
(Pandas) apply a function to a pd.Series to create two new columns in the pd.DataFrame
Did you check what df['example_text'].apply(split_string) actually outputs? example_text | 0 | (['hello!', 'I', 'love', 'my', 'dog!'], 'hello!Ilovemydog!') | 1 | (['hi!', 'I', 'like', 'my', 'cat!'], 'hi!Ilikemycat!') | 2 | (['greetings!', 'I', 'hate', 'my', 'goldfish!'], 'greetings!Ihatemygoldfish!') As Series where each row element is a tuple. You can't simply assign this to two columns. If you want to expand this into two columns try: df[['list_of_words','melted_text']] = pd.DataFrame(df['example_text'].apply(split_string).to_list()) Basically, you create a new dataframe from it, which you then can assign to multiple columns. More on reddit.com
🌐 r/learnpython
2
1
October 24, 2022
python - Expand pandas DataFrame column into multiple rows - Stack Overflow
Self-reply: first replace the Nones ... so pandas won't freak out. Then remove the reset_index. Move join before stack and optionally set the name-field as index before stacking to avoid repeating it. Afterwards replace placeholders with NaN. 2018-08-04T08:15:26.207Z+00:00 ... df2 = pd.DataFrame(columns = df.columns) ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.core.window.expanding.Expanding.apply.html
pandas.core.window.expanding.Expanding.apply — pandas 2.3.3 documentation
Aggregating apply for DataFrame. ... >>> ser = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']) >>> ser.expanding().apply(lambda s: s.max() - 2 * s.min()) a -1.0 b 0.0 c 1.0 d 2.0 dtype: float64
🌐
GeeksforGeeks
geeksforgeeks.org › python › return-multiple-columns-using-pandas-apply-method
Return multiple columns using Pandas apply() method - GeeksforGeeks
July 15, 2025 - # Using pandas.DataFrame.apply() on the data frame print('Returning multiple columns from Pandas apply()') dataFrame.apply(lambda x: [1, 2], axis = 1) ... Passing result_type=’expand’ will expand list-like results to columns of a Dataframe.
🌐
Reddit
reddit.com › r/learnpython › (pandas) apply a function to a pd.series to create two new columns in the pd.dataframe
r/learnpython on Reddit: (Pandas) apply a function to a pd.Series to create two new columns in the pd.DataFrame
October 24, 2022 -

As a toy example, I have a function that takes a string, and returns the string without spaces + a list of words (separated by spaces) in the string:

def split_string(text):
    list_of_words = text.split(' ')
    melted_text = ''.join(list_of_words)
    return list_of_words, melted_text

And I want to be able to apply this function to a pd.Series (a column of all string values) and return the list_of_words and melted_text columns:

df = pd.DataFrame(data={'example_text': [
    'hello! I love my dog!',
    'hi! I like my cat!',
    'greetings! I hate my goldfish!']})

I then try to apply the function on the example_text column:

df[['list_of_words','melted_text']] = df['example_text'].apply(split_string)

but receive this error:

ValueError: Columns must be same length as key

Any idea what I'm doing wrong?

🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.DataFrame.expanding.html
pandas.DataFrame.expanding — pandas 3.0.1 documentation
An expanding window yields the value of an aggregation statistic with all the data available up to that point in time. ... Minimum number of observations in window required to have a value; otherwise, result is np.nan. methodstr {‘single’, ‘table’}, default ‘single’ · Execute the rolling operation per single column or row ('single') or over the entire object ('table').
Find elsewhere
Top answer
1 of 8
25

You could use df.itertuples to iterate through each row, and use a list comprehension to reshape the data into the desired form:

import pandas as pd

df = pd.DataFrame( {"name" : ["John", "Eric"], 
               "days" : [[1, 3, 5, 7], [2,4]]})
result = pd.DataFrame([(d, tup.name) for tup in df.itertuples() for d in tup.days])
print(result)

yields

   0     1
0  1  John
1  3  John
2  5  John
3  7  John
4  2  Eric
5  4  Eric

Divakar's solution, using_repeat, is fastest:

In [48]: %timeit using_repeat(df)
1000 loops, best of 3: 834 µs per loop

In [5]: %timeit using_itertuples(df)
100 loops, best of 3: 3.43 ms per loop

In [7]: %timeit using_apply(df)
1 loop, best of 3: 379 ms per loop

In [8]: %timeit using_append(df)
1 loop, best of 3: 3.59 s per loop

Here is the setup used for the above benchmark:

import numpy as np
import pandas as pd

N = 10**3
df = pd.DataFrame( {"name" : np.random.choice(list('ABCD'), size=N), 
                    "days" : [np.random.randint(10, size=np.random.randint(5))
                              for i in range(N)]})

def using_itertuples(df):
    return  pd.DataFrame([(d, tup.name) for tup in df.itertuples() for d in tup.days])

def using_repeat(df):
    lens = [len(item) for item in df['days']]
    return pd.DataFrame( {"name" : np.repeat(df['name'].values,lens), 
                          "days" : np.concatenate(df['days'].values)})

def using_apply(df):
    return (df.apply(lambda x: pd.Series(x.days), axis=1)
            .stack()
            .reset_index(level=1, drop=1)
            .to_frame('day')
            .join(df['name']))

def using_append(df):
    df2 = pd.DataFrame(columns = df.columns)
    for i,r in df.iterrows():
        for e in r.days:
            new_r = r.copy()
            new_r.days = e
            df2 = df2.append(new_r)
    return df2
2 of 8
21

New since pandas 0.25 you can use the function explode()

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html

import pandas as pd
df = pd.DataFrame( {"name" : "John", 
               "days" : [[1, 3, 5, 7]]})

print(df.explode('days'))

prints

   name days
0  John    1
0  John    3
0  John    5
0  John    7
Top answer
1 of 3
1

This addresses the problem, not the general issue of passing multiple columns: I would use groupby and cummax, and then see whether we hit a new value. For example:

grouped = df.groupby("id")["value"]
cummax = grouped.cummax()
cummax_is_new_value = cummax != cummax.groupby(df.id).shift()
df["new_max"] = cummax_is_new_value.astype(int)

gives me

>>> df
    id  value  new_max
0    0      1        1
1    0      3        1
2    0      2        0
3    0      5        1
4    0      4        0
5    1      4        1
6    1      3        0
7    1      2        0
8    1      1        0
9    1      5        1
10   2      1        1
10   2      1        0
10   2      0        0
10   2      1        0
10   3      1        1

Originally I was only checking whether the value was the same as the previous value, but that failed on cases like [1, 0, 1], where the second 1 is both equal to the cumulative maximum and not the same as the previous value. This way we're always working with the grouped cumulative values, and so we really are only picking up the new cumulative values by group.

2 of 3
0

Its been a long time since I worked with apply like a couple releases ago minimum, so my recollection may be bad, or things may have changed. However, as I remember it the grouped data is passed automatically as the first argument.

The temptation when passing your own function to apply is to do this:

def user_func(df, arg1, arg2):
    return whatever_you_like

DF = pd.DataFrame(your_data)

DF.groupby('col1').appy(user_func(arg1, arg2))

but this is not the correct syntax. In fact the correct syntax for the last line is

DF.groupby('col1').apply(user_func, arg1, arg2)

Whether expanding_apply works in the same way I do not know and this may all be totally out of date, but might be worth a shot.

🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.23 › generated › pandas.DataFrame.apply.html
pandas.DataFrame.apply — pandas 0.23.1 documentation
In the current implementation apply calls func twice on the first column/row to decide whether it can take a fast or slow code path. This can lead to unexpected behavior if func has side-effects, as they will take effect twice for the first column/row. ... Returning a Series inside the function is similar to passing result_type='expand'.
🌐
Datasciencebyexample
datasciencebyexample.com › 2023 › 03 › 15 › expand-array-column-in-pandas
Expanding Array Columns in Pandas DataFrames and wrap up in scikit-learn transformer | DataScienceTribe
March 15, 2023 - To illustrate how to expand an array column in a Pandas DataFrame, let’s start with an example DataFrame that contains a column of arrays: This DataFrame has a single column named array_col with three rows, each containing an array of three integers. To expand this column into multiple columns, we can use the apply ...
🌐
Vultr Docs
docs.vultr.com › python › third-party › pandas › DataFrame › explode
Python Pandas DataFrame explode() - Transform Each Iterable | Vultr Docs
December 24, 2024 - The elements in each list become separate rows, with all other column values repeated for these new rows. Start with a DataFrame where multiple columns contain iterables. Apply explode() to each of these columns one by one.
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-apply-a-function-to-multiple-columns-in-pandas
How to Apply a function to multiple columns in Pandas? - GeeksforGeeks
July 15, 2025 - Pandas.apply allow the users to pass a function and apply it on every single value of the Pandas series. Syntax : DataFrame.apply(parameters) Parameters : func : Function to apply to each column or row. axis : Axis along which the function is applied · raw : Determines if row or column is passed as a Series or ndarray object. result_type : ‘expand’, ‘reduce’, ‘broadcast’, None; default None ·
🌐
Moonbooks
en.moonbooks.org › Articles › How-to-apply-a-function-to-a-DataFrame-column-with-pandas-in-python-
How to apply a function to an individual or multiple columns of a pandas DataFrame ?
This can be done using the DataFrame.apply() method which takes in the desired function as its first argument and returns a pandas object with the newly-created variables. The apply() method also has an optional axis argument with the default value of 0, which specifies how the function should ...
Top answer
1 of 2
2

An possible solution is to make the expanding part of the function, and use GroupBy.apply:

def foo1(_df):
    return _df['x1'].expanding().max() * _df['x2'].expanding().apply(lambda x: x[-1], raw=True)

df['foo_result'] = df.groupby('group').apply(foo1).reset_index(level=0, drop=True)
print (df)
  group  time   x1  x2  foo_result
0     A     1   10   1        10.0
3     B     1  100   2       200.0
1     A     2   40   2        80.0
4     B     2  200   0         0.0
2     A     3   30   1        40.0
5     B     3  300   3       900.0

This is not a direct solution to the problem of applying a dataframe function to an expanding dataframe, but it achieves the same functionality.

2 of 2
2

Applying a dataframe function on an expanding window is apparently not possible (at least not for pandas version 0.23.0; EDITED - and also not 1.3.0), as one can see by plugging a print statement into the function.

Running df.groupby('group').expanding().apply(lambda x: bool(print(x)) , raw=False) on the given DataFrame (where the bool around the print is just to get a valid return value) returns:

0    1.0
dtype: float64
0    1.0
1    2.0
dtype: float64
0    1.0
1    2.0
2    3.0
dtype: float64
0    10.0
dtype: float64
0    10.0
1    40.0
dtype: float64
0    10.0
1    40.0
2    30.0
dtype: float64

(and so on - and also returns a dataframe with '0.0' in each cell, of course).

This shows that the expanding window works on a column-by-column basis (we see that first the expanding time series is printed, then x1, and so on), and does not really work on a dataframe - so a dataframe function can't be applied to it.

So, to get the obtained functionality, one would have to put the expanding inside the dataframe function, like in the accepted answer.

🌐
Spark By {Examples}
sparkbyexamples.com › home › pandas › pandas apply() function to single & multiple column(s)
Pandas apply() Function to Single & Multiple Column(s) - Spark By {Examples}
December 6, 2024 - When applied to a single column, apply() iterates over each element of the column, applying the specified function. For multiple columns, apply() can operate on either rows or columns, based on the axis parameter.
🌐
CopyProgramming
copyprogramming.com › howto › in-pandas-how-do-i-expand-into-multiple-columns-an-applied-function-that-returns-a-dataframe
Python: Expanding a Function's Returned Dataframe into Multiple Columns in Pandas
April 21, 2023 - The DataFrame.apply function in ... this parameter only applies when the axis is set to 1 (columns). If the result_type is set to 'expand', the list-like results will be transformed into columns....
🌐
Kanoki
kanoki.org › 2022 › 02 › 11 › how-to-return-multiple-columns-using-pandas-apply
How to return multiple columns using pandas apply | kanoki
February 11, 2022 - In this article we are going to compare the performance of two approaches i.e. Apply method and Vectorization which can be used to apply a function on dataframe and return multiple new columns · we will be following the below steps to create those multiple columns for a dataframe using a custom function: Create a dataframe with 10K rows and two columns name and size(bytes) respectively · Build a function to convert the size to Kilobytes(kb), Megabytes(MB) and Gigabytes(GB) Use pandas.Series.apply() to apply the function created in Step#2 above to create three new columns size_kb, size_mb and size_gb respectively
🌐
Studytonight
studytonight.com › pandas › pandas-dataframe-expanding-method
Pandas DataFrame expanding() Method - Studytonight
In the below example, the DataFrame.expanding() method calculated the cumulative sum of the selected column in the DataFrame and store the result in the other column. import pandas as pd df = pd.DataFrame({"A": [1, 2, 3],"B": [1, 1, 1]}) print("---The DataFrame is---") print(df) print("------Output of the function is-------") df["result"]=df.A.expanding().sum() print(df)