首页 > 解决方案 > 更新通过 DataFrame.groupby.apply 调用的函数内部的 pandas 数据框

问题描述

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

我有一个数据框。我想做一个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还有其他解决方案吗?我明白我可以简单地让函数创建一个新系列并在最后分配它:

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

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

标签: pandasdataframe

解决方案


看来 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")

推荐阅读