如何用Pandas/Numpy无循环计算数据列中连续数据点的均值
问题
我想用非循环的方式(循环在大数据集上太耗时)计算数据列中连续两个数据点的平均值,不用手动减去最后一个索引。目前我只能通过遍历列索引并在循环范围里减去最后一个索引来实现,想知道有没有Pandas或Numpy的高效方法。
现有实现代码及数据
import pandas as pd df = pd.read_csv('class_data.dat',sep='\t') df
对应的DataFrame输出:
Age BMI Gender 0 23.0 17.2 Male 1 25.6 16.3 Female 2 26.4 22.5 Female 3 43.2 33.0 Male 4 22.5 21.8 Male 5 19.4 29.6 Male 6 20.5 34.6 Female 7 22.7 27.2 Female 8 17.5 15.5 Male
现有循环实现代码:
BMI_means = {} for i in range(len(df)-1): BMI_means[i] = (df.BMI[i] + df.BMI[i+1])/2 BMI_means
输出结果:
{0: 16.75, 1: 19.4, 2: 27.75, 3: 27.4, 4: 25.700000000000003, 5: 32.1, 6: 30.9, 7: 21.35}
高效解决方案
Pandas 实现
利用shift()方法实现向量运算,无需手动处理索引范围:
# 计算连续两个BMI值的平均值 bmi_means_pd = (df['BMI'] + df['BMI'].shift(-1)) / 2 # 移除最后一行的NaN(最后一个元素无后续值) bmi_means_pd = bmi_means_pd.dropna() # 转为与原输出一致的字典格式 bmi_means_pd.to_dict()
执行后得到的结果和循环实现完全相同。shift(-1)会将列元素向下移位,最后一行生成NaN,删除后即得到目标结果,全程为Pandas优化后的向量运算,效率远高于循环。
Numpy 实现
通过数组切片直接计算,底层优化的操作适合超大数据集:
import numpy as np # 将BMI列转为Numpy数组 bmi_array = df['BMI'].values # 取前n-1个元素与后n-1个元素计算平均值 bmi_means_np = (bmi_array[:-1] + bmi_array[1:]) / 2 # 转为字典格式 dict(enumerate(bmi_means_np))
输出结果同样与原循环实现一致,Numpy切片操作的计算速度极快,是处理大规模数据的最优选择之一。
内容的提问来源于stack exchange,提问作者Marble_gold
相关产品推荐
相关产品推荐

