我经常发现自己试图做出等同于groupby
然后mutate
的R等等,但很多人都指出只使用groupby
和apply
受到主要影响性能问题。所以我的问题是,根据该组中的某些条件,在pandas中对数据帧进行分组的最佳方法是什么,根据某些计算添加新列?
我已经搜索过并且没有找到任何关于如何使用numpy在pandas中矢量化自定义函数的指南/步骤。所有类似问题的答案都是针对用户的,并且不能很好地概括。
编辑:澄清问题功能并添加玩具数据
df
Out[17]:
ID ID2 col1 col2 col3 value
0 1 J 333.5 333.3 333.4 cat
1 1 S 333.5 333.3 333.8
2 2 J 333.7 333.3 333.8 cat
3 2 S 333.7 333.3 333.4 dog
4 3 L 333.7 333.8 333.9
5 3 D 333.8 333.8 333.9
6 4 S 333.8 333.6 333.7 cat
7 4 J 333.8 333.2 333.8
8 4 J 333.8 333.7 333.9
9 4 L 333.8 333.3 333.4 cat
以下是一些例子,我经常遇到:
df.groupby(by=['ID']).apply(myfunc)
def myfunc(group):
group['new_col'] = len(group.query('''ID2=='T' & (col1>=col3 | px<=col2)''').unique())
return group
df.groupby(by=['ID']).apply(update_func)
def update_func(group):
if 'S' in group['ID2'].values:
group.loc[(group['value']=='cat'), 'other_column'] = False
return group
答案 0 :(得分:1)
我认为您不需要在groupby中进行屏蔽,让我们看看这是否适用于您。
d1 = df.assign(mask=np.logical_and(df.ID2 == 'J', (np.logical_or((df.col1 >= df.col3), (df.col1 <= df.col2)))))
dict = d1.groupby('ID').apply(lambda x: x.loc[x['mask'],'col1'].size).to_dict()
答案 1 :(得分:0)
对于第一个示例,我使用numpy
运算符改进了函数,并且建议使用@ScottBoston,我更改了函数以仅返回值,然后将它们映射回原始数据帧:
def my_func(group):
mask = np.logical_and(group.ID2 == 'J', (np.logical_or((group.col1 >= group.col3), (group.col1 <= group.col2))))
return len(group[mask].col1.unique())
dict = df.groupby(by=['ID'], sort=False).apply(my_func).to_dict() #This is a bit slow
df['new_col'] = df['ID'].map(dict) #This is fast
最慢的部分仍然是必须对每个组进行操作的numpy
条件的应用。如果有一种方法可以对每一个并行操作,那么这将是理想的,因为不需要像现在那样按顺序进行操作。