Python 使用groupby->;在多个列上执行函数时,在数据帧上执行转换(func),优先考虑速度
假设我有一个数据帧:Python 使用groupby->;在多个列上执行函数时,在数据帧上执行转换(func),优先考虑速度,python,pandas,dataframe,join,pandas-groupby,Python,Pandas,Dataframe,Join,Pandas Groupby,假设我有一个数据帧: df= pd.DataFrame({'grouping_col':['B','B','S','S','S','B'],'column1':[10,20,30,40,50,60],'column2':[5,6,7,8,9,10],'column3':[11,12,13,14,15,16],'column4':[16,17,18,19,20,21]}) df.set_index('grouping_col',inplace= True) 假设我有一个函数 def func(
df= pd.DataFrame({'grouping_col':['B','B','S','S','S','B'],'column1':[10,20,30,40,50,60],'column2':[5,6,7,8,9,10],'column3':[11,12,13,14,15,16],'column4':[16,17,18,19,20,21]})
df.set_index('grouping_col',inplace= True)
假设我有一个函数
def func(x,col1,col2,col3,col4):
return sum(x[col1]**2 * x[col2] * x[col3] * x[col4]) / sum(x[col1]**2 *x[col3]**2 * x[col4]**2)
我试图在数据帧上使用GROUPBY,然后应用该函数。有效的方法是:
new_col= df.groupby('grouping_col').apply(func,'column1','column2','column3','column4').rename('new_col_name')
df = df.join(new_col,how= 'left')
print(df)
column1 column2 column3 column4 new_col_name
grouping_col
B 10 5 11 16 0.029738
B 20 6 12 17 0.029738
B 60 10 16 21 0.029738
S 30 7 13 18 0.030011
S 40 8 14 19 0.030011
S 50 9 15 20 0.030011
这很好,但我需要在更大/更复杂的数据帧上应用此函数数千次,并且连接需要花费不合理的长时间,因此我尝试提出一种更快的方法
到目前为止,我已经尝试:
df['new_col_name'] = df.groupby('grouping_col').transform(lambda x: func(x,'column1','column2','column3','column4'))
result: KeyError: ('column1', 'occurred at index column1')
所以我猜它不起作用,因为转换分别对每一列进行操作。有谁有更好的主意吗?提前谢谢 一个可能的想法是在使用groupby之前计算数学运算的分子
n
和分母d
,然后使用对数据帧索引上的分子和分母进行分组,最后使用sum
转换分子和分母
n = df['column1']**2 * df['column2'] * df['column3'] * df['column4']
d = df['column1']**2 * df['column3']**2 * df['column4']**2
df['new_col_name'] = (
n.groupby(df.index).transform('sum') /
d.groupby(df.index).transform('sum')
)
或者
结果:
# print(df)
column1 column2 column3 column4 new_col_name
grouping_col
B 10 5 11 16 0.029738
B 20 6 12 17 0.029738
S 30 7 13 18 0.030011
S 40 8 14 19 0.030011
S 50 9 15 20 0.030011
B 60 10 16 21 0.029738
这真是好东西。最后一个问题:有没有办法只使用一个groupby?@Vincent_Adultman你可以,但我认为在性能方面没有任何明显的改进。如果你愿意,我可以给你看……是的,如果你不介意的话,我有点好奇。不管怎样,我都会把你的答案标为正确。
# print(df)
column1 column2 column3 column4 new_col_name
grouping_col
B 10 5 11 16 0.029738
B 20 6 12 17 0.029738
S 30 7 13 18 0.030011
S 40 8 14 19 0.030011
S 50 9 15 20 0.030011
B 60 10 16 21 0.029738