如何用Scipy和Pandas向量化拟合正态分布并生成loc、scale列?
提升正态分布拟合速度的向量化方案
首先明确:scipy.stats.norm.fit对正态分布的拟合结果,loc就是样本均值,scale就是无偏样本标准差(除以n-1)——所以没必要绕路调用fit函数,直接用Pandas/Numpy的向量化方法计算,速度能追上甚至超过你提到的Numpy直接计算的效率。
两种向量化实现方案
1. 当所有数值列表长度相同时
这种情况可以直接把列转成二维Numpy数组,用轴方向的向量化运算:
import pandas as pd import numpy as np # 示例数据:每行是长度一致的数值列表 df = pd.DataFrame({'values': [np.random.normal(5, 2, 100) for _ in range(100)]}) # 将列表列转为二维数组 values_arr = np.array(df['values'].tolist()) # 向量化计算loc和scale(ddof=1对应scipy无偏标准差的逻辑) df['loc'] = values_arr.mean(axis=1) df['scale'] = values_arr.std(axis=1, ddof=1)
2. 当数值列表长度不同时
用explode展开列表后分组统计,同样是向量化操作:
# 示例数据:每行是长度不一的数值列表 df = pd.DataFrame({'values': [np.random.normal(5, 2, np.random.randint(50, 150)) for _ in range(100)]}) # 展开列表并按原行索引分组计算 expanded_df = df.explode('values').reset_index() grouped_stats = expanded_df.groupby('index')['values'].agg( loc='mean', scale=lambda x: x.std(ddof=1) ) # 将统计结果合并回原DataFrame df = df.join(grouped_stats)
为什么这两种方法更快?
pd.apply本质还是在Python层面逐行循环,而上述方案利用了Pandas/Numpy底层的C实现,完全避免了Python循环的开销,效率和直接用Numpy计算处于同一量级。
如果你的数据确实符合正态分布,直接用均值+无偏标准差的向量化计算,结果和norm.fit完全一致,但速度会快很多——甚至比你提到的字典循环还要高效。
内容的提问来源于stack exchange,提问作者Jason H
相关产品推荐
相关产品推荐

