更新通过DataFrame.groupby.apply调用的函数中的熊猫数据框

时间:2018-09-24 20:56:56

标签: pandas dataframe

这似乎是一个非常基本的问题,之前曾有人问过,但我找不到答案。

我有一个数据框。我想做一个groupby,然后应用一个函数。我希望函数修改原始数据框中的列。这些选项都不起作用:

import pandas as pd
df = pd.DataFrame(list(zip(list('abababa'), [1,2,3,4,1,2,3], [5,4,3,2,1,2,3])), 
                  columns=["ab", "x", "y"])
print(df,"\n")

### Attempt #1
def change_y(tab):
    tab.y = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #2
def change_y(tab):
    tab.loc[:,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #3
def change_y(tab):
    tab.at[:,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

### Attempt #4
def change_y(tab):
    tab.loc[tab.index,"y"] = tab.y.min()

df.groupby(df.ab).apply(change_y)

但是,这可行:

### Attempt #5 -- This one works
def change_y(big_tab,tab):
    big_tab.loc[tab.index,"y"] = tab.y.min()

df.groupby(df.ab).apply(lambda tab: change_y(df,tab))
print(df,"\n")

因此,我了解了#5为何起作用,但我不明白为什么1-4都不起作用。我误会了groupby吗?我认为它没有复制基础数据框,而只是在基础数据框上构造索引并将它们传递给函数。在这种情况下,似乎1-4中的至少一个应该可以工作!

groupby实际上是否为每个组制作数据帧的副本?看来这是不必要且低效的。

如果确实进行复制,则除了#5之外,还有其他解决方案吗?我确实知道我可以简单地让函数创建一个新的Series并在最后分配它:

df.y = df.groupby(df.ab).apply(lambda tab: tab.x = tab.y)

但是由于其他原因,在这种情况下,我不想这样做。

1 个答案:

答案 0 :(得分:0)

看来,groupby实际上确实在制作副本。我想避免这种情况,因为我有一个非常庞大的数据框。我确实提出了这个解决方案,就像我的数据框很大一样丑陋。我只需要复制数据框的一列。 (它可以是任何列;我只对索引感兴趣。)

感谢所有提供帮助的人。

import pandas as pd
df = pd.DataFrame(list(zip(list('abababa'), [1,2,3,4,1,2,3], [5,4,3,2,1,2,3])), 
                  columns=["ab", "x", "y"])
print(df,"\n")

def change_y(big_tab,ab_tab):
    indx = ab_tab.index
    tab = big_tab.loc[indx]  # I can do all but the update with tab.
    big_tab.loc[indx,"y"] = tab.y.min()

df.ab.groupby(df.ab).apply(lambda ab_tab: change_y(df,ab_tab))
print(df,"\n")