Update a dataframe within apply after using groupby

Viewed 4071

I have a pandas dataframe that I want to group on and then update the original dataframe using iterrows and set_value. This doesn't appear to work.

Here is an example.

In [1]: def func(df, n):
   ...:     for i, row in df.iterrows():
   ...:         print("Updating {0} with value {1}".format(i, n))
   ...:         df.set_value(i, 'B', n)

In [2]: df = pd.DataFrame({"A": [1, 2], "B": [0, 0]})

In [3]: df
Out[4]:
   A  B
0  1  0
1  2  0

In [125]: func(df, 1)
Updating 0 with value 1
Updating 1 with value 1

In [126]: df
Out[126]:
   A  B
0  1  1
1  2  1

In [127]: df.groupby('A').apply(lambda df: func(df, 2))
Updating 0 with value 2
Updating 0 with value 2
Updating 1 with value 2
In [126]: df
Out[126]:
   A  B
0  1  1
1  2  1

I was hoping that B would have been updated to 2.

Why isn't this working, and what is the best way to achieve this result?

3 Answers

In some situations, if func() does things based on index, you could modify the original dataframe directly.

Instead of this:

def func(group, n):
    for i, row in group.iterrows():
        print("Updating {0} with value {1}".format(i, n))
        group.set_value(i, 'B', n)
    return group

df.groupby('A').apply(lambda group: func(group, 2))

You could do this:

for key, group in df.groupby('A'):
    n = 2
    for i, row in group.iterrows():
        print("Updating {0} with value {1}".format(i, n))
        df.set_value(i, 'B', n)
Related