迭代使用groupby+apply时更新列表项



我在数据框架上使用groupby+apply方法,并将应用函数的返回值存储在新列中。

初始数据帧df:

In[1]:  df
Out[1]: 
tag    a   b 
0     tag1   15   1 
1     tag1   26   2 
2     tag2   20   2 
3     tag3   11   3 
4     tag3   15   3 
5     tag3   24   4  

groupby+应用程序如下:

In[2]:  grouped = df.groupby('tag')
In[3]:  df['a+b'] = grouped.get_group('tag1').apply(function,axis=1)
In[4]:  df
Out[4]:     
tag    a   b  a+b
0     tag1   15   1   16
1     tag1   26   2   28
2     tag2   20   2  nan
3     tag3   11   3  nan
4     tag3   15   3  nan 
5     tag3   24   4  nan 
In[5]:  df['a+b'] = grouped.get_group('tag2').apply(function,axis=1) 
In[6]:  df
Out[6]:     
tag    a   b  a+b
0     tag1   15   1  nan
1     tag1   26   2  nan
2     tag2   20   2   22
3     tag3   11   3   14
4     tag3   15   3  nan 
5     tag3   24   4  nan  

首先,我选择将函数仅应用于带有'tag1'的条目。在最初的情况下,这是因为所使用的数据框架非常大,而我只对应用该函数的少数特定组感兴趣。

您可以从In[5]以后看到的问题是,当在In[3]InIn[5]中为不同组重复In中的代码时,组'tag1'的列'a+b'中的条目将在此过程中丢失。

我怎样才能找到一种方法来简单地更新'a+b'的列项而不覆盖?有没有针对这类问题的最佳实践示例?

看起来你的函数只是沿着轴1求和列,所以你可以只是求和,然后过滤你想要的行。

df.assign(ab=df.sum(axis=1)).loc[df['first'].isin(['tag1', 'tag2'])]
first   a  b  ab
0  tag1  15  1  16
1  tag1  26  2  28
2  tag2  20  2  22

我认为在这种情况下您不需要groupby。您可以保存想要应用该函数的标记,然后执行如下操作:

desired_tags = ['tag1', 'tag2']
df['a+b'] = (df[df['tag'].isin(desired_tags)]
.apply(function, axis=1))

输出如下:

tag   a  b   a+b
0  tag1  15  1  16.0
1  tag1  26  2  28.0
2  tag2  20  2  22.0
3  tag2  11  3  14.0
4  tag3  15  3   NaN
5  tag3  24  4   NaN

我假设你的function是这样的:

function = lambda df: df['a'] + df['b']

这样你可以只运行一次命令

您可以轻松地选择df['a+b']列的非空部分:

df.loc[df['a+b'].isnull(), 'a+b'] = grouped.get_group('tag2').apply(function, axis=1)

这是我发现最有效的方法。我使用pandas.Series.update()来更新Dataframe的单个列:

for key, item in grouped:
series = grouped.get_group(key).apply(function,axis=1)
if 'a+b' in df.columns :
df['a+b'].update(series)
else:
df['a+b'] = series

这段代码效果最好,因为我需要将函数迭代地应用于每个组(或指定的一组或多组),而不是一次应用于所有组。这是必需的,因为有限的内存容量,也因为我只需要为少数组应用函数的信息。

对这段代码的任何评论都非常感谢!

最新更新