基于Pandas DataFrame计算百分比偏差的技术实现求助
Pandas分组计算偏差及Seaborn回归图实现
原始数据
首先定义你的DataFrame:
import pandas as pd df = pd.DataFrame({ 'setting_id': [7,7,7,7,7,7,7,7,7], 'subject_id': [1,1,1,2,2,2,3,3,3], 'seconds': [0,3600,10800,0,3600,10800,0,3600,10800], 'result_id': [1680.5,1690.5,1700.5,1682.5,1692.5,1702.5,1684.5,1694.5,1704.5], 'owner_id': [2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0], 'average': [24.0,46.0,101.0,12.5,33.5,86.5,8.5,15.0,34.0], 'duration_id': [1.0,2.0,4.0,1.0,2.0,4.0,1.0,2.0,4.0] })
需求说明
按setting_id和subject_id分组,计算每组内seconds≠0的average相对于seconds=0的average的百分比偏差,公式为(result/baseline)*100,其中baseline是同组内seconds=0的average值;seconds=0的行偏差设为0。
实现步骤
1. 计算偏差列
用Pandas的分组transform方法实现,避免循环,效率更高:
# 提取每组的基准值(seconds=0的average) baseline = df.groupby(['setting_id', 'subject_id'])['average'].transform( lambda x: x[df.loc[x.index, 'seconds'] == 0].iloc[0] ) # 计算偏差,seconds=0的行设为0,其余行按公式计算后取整 df['deviation'] = df.apply( lambda row: 0 if row['seconds'] == 0 else round((row['average'] / baseline[row.name]) * 100), axis=1 ) # 可选:将float类型的owner_id、duration_id转为int,匹配示例格式 df[['owner_id', 'duration_id']] = df[['owner_id', 'duration_id']].astype(int)
处理后的结果如下(截取前3行):
setting_id subject_id seconds result_id owner_id average duration_id deviation 0 7 1 0 1680.5 2 24.00 1 0 1 7 1 3600 1690.5 2 46.00 2 192 2 7 1 10800 1700.5 2 101.00 4 421
2. Seaborn绘制偏差回归图
导入库后,筛选数据并绘制回归图:
import seaborn as sns import matplotlib.pyplot as plt # 筛选非0秒的数据用于绘图 plot_df = df[df['seconds'] != 0] # 绘制带分组的回归图,按subject_id区分颜色和标记 sns.lmplot(x='seconds', y='deviation', data=plot_df, hue='subject_id', markers=['o', 's', 'D']) plt.title('Deviation vs. Seconds Regression') plt.xlabel('Elapsed Seconds') plt.ylabel('Deviation (%)') plt.show()
这段代码会生成每个subject的偏差随秒数变化的回归趋势图,清晰展示数据规律。
内容的提问来源于stack exchange,提问作者drevil
相关产品推荐
相关产品推荐

