python - 并行化 groupby:将函数同时应用于 groupby 对象
问题描述
我想按操作执行分组,并为每个组估计一个线性模型。
编写一个函数然后使用for 循环非常容易,但是有点慢。
这是一个玩具示例,但它确实起到了作用。在您看来,使这种并行化的“最佳”方式是什么?
一个直观的例子:
import seaborn as sns
import pandas as pd
from statsmodels.formula.api import ols
import time
# Dataset
df = sns.load_dataset("tips")
df.head()
# Groupby the dataset
df_grouped = df.groupby(["day"])
# Some function to be applied for every grouped element
def regression_model(df):
"""
This function estimates a linear regression model and returns coefs as dictionary
"""
model = ols('tip ~ total_bill + C(sex) + size', data = df)
return dict(model.fit().params)
# Performing the function in the for loop ------ Slow. We want to perform it for each grouped element simultaneously.
coefs_dict = {}
for i, j in df_grouped:
coefs_i = regression_model(j)
coefs_dict[i] = coefs_i
# Artificial sleep so we can demostrate that the "mechanical" for loop is slow....
time.sleep(2)
在这种特殊情况下,我使用“睡眠”模块来使其更慢,以证明 for 循环将花费大量时间,特别是如果我们将按更多数量的独特类别进行分组。
解决方案
您可以multiprocessing
按照@JérômeRichard 的建议使用模块,并Pool.starmap
使用groupby
import pandas as pd
import multiprocessing
def regression_model(keys, df):
print(f'Pool: {keys}')
# do stuff here
return df
if __name__ == '__main__':
data = []
with multiprocessing.Pool(multiprocessing.cpu_count()) as pool:
data = pool.starmap(regression_model, df.groupby('day'))
df2 = pd.concat(data)
推荐阅读
- php - 用微时间测量持续时间随机结果为零
- c# - 最佳实践:属性、函数还是 ToString?
- excel - VBA Word更改表格单元格中特定单词的字体大小
- c# - Razor 类库 MSBuild MSB4062 编译期间出错
- javascript - 为什么在这个不可变 JS 测试中 equals 很慢?
- php - 为什么我在这方面遇到这么多麻烦:
- javascript - 显示/隐藏独特的 div
- intellij-idea - 更改 WebStorm 上选定文本的背景颜色?
- java - 从 Parent 类型的实例调用 child 的方法
- objective-c - 如果使用 NSMutableArray 而不是 NSArray,应用程序崩溃