我在数据框架上使用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
这段代码效果最好,因为我需要将函数迭代地应用于每个组(或指定的一组或多组),而不是一次应用于所有组。这是必需的,因为有限的内存容量,也因为我只需要为少数组应用函数的信息。
对这段代码的任何评论都非常感谢!