如何在Pandas GROUPBY中高效应用Logit模型替代循环?
对分组DataFrame高效应用Logit模型的方法
你的思路完全没问题,groupby.apply确实能实现对每个分组单独拟合Logit模型的需求,而且比手动写循环更优雅高效,但你的函数写法需要调整一下,我来给你梳理清楚:
一、修正你的函数写法
你写的elegant函数有两个小问题:
- 参数用了
self,但groupby.apply会把每个分组的子DataFrame传递给函数,参数应该对应这个子数据集; - 函数里直接用了全局的
data,应该改用传入的分组数据,不然会一直用整个数据集拟合,达不到分组的效果。
修正后的完整代码如下:
import pandas as pd import numpy as np import statsmodels.api as sm # 生成测试数据 df1=pd.DataFrame(np.random.randint(0,100,size=(100,10)),columns=list('abcdefghij')) df2=pd.DataFrame(np.random.randint(0,100,size=(100,10)),columns=list('abcdefghij')) df1['model']=1 df1['target']=np.random.randint(2,size=100) df2['model']=2 df2['target']=np.random.randint(2,size=100) data=pd.concat([df1,df2]) # 定义拟合Logit模型的函数 def fit_logit(group): # 提取因变量和自变量 y = group['target'] # 注意要去掉model列,避免它被当成自变量 X = sm.add_constant(group.drop(['target', 'model'], axis=1)) # 拟合模型,关闭迭代输出 lm = sm.Logit(y, X).fit(disp=0) # 返回模型的简洁摘要 return lm.summary2() # 分组应用函数 result = data.groupby(['model']).apply(fit_logit) # 查看结果 print(result)
如果想保存模型对象而不是直接输出摘要,也可以让函数返回模型本身,方便后续调用:
def fit_logit_model(group): y = group['target'] X = sm.add_constant(group.drop(['target', 'model'], axis=1)) return sm.Logit(y, X).fit(disp=0) models = data.groupby(['model']).apply(fit_logit_model) # 调用model=1的模型摘要 print(models[1].summary2())
二、效率对比:groupby.apply vs 手动循环
groupby.apply本质上也是循环,但它比你写的手动循环更高效:
- 手动循环里每次都要做
data[data['model']==i]的切片操作,这会重复生成新的DataFrame,带来额外的内存和计算开销; - pandas的
groupby会提前完成一次分组操作,内部处理时直接调用分好的子数据集,避免了重复切片的冗余操作,而且底层实现经过了优化,在数据量越大时,这种效率优势越明显。
另外,groupby.apply的代码更简洁易读,后续维护和扩展也更方便——比如之后要加更多分组变量,只需要修改groupby的参数就行,不用调整循环逻辑。
内容的提问来源于stack exchange,提问作者Kyle
相关产品推荐
相关产品推荐

