Python按ITEM分组计算CSV历史数据均值方差生成未来ATP值问题求助
问题根因
- 字段名不统一:历史数据筛选ITEM用的字段是
Item.[Item],未来数据分组用的是Item,字段不一致会导致匹配错误 - 结果顺序错位:你把不同ITEM的计算结果按循环顺序拼到列表后,直接赋值给
future_data的新列,但future_data的行顺序和你循环计算的顺序不一定匹配,自然出现数据混淆 - 没必要将
Sched_Quantity拼接为字符串再拆分,直接按行匹配ITEM的统计值计算更稳妥
优化方案
你提到的用字典存储各ITEM的统计值是非常合适的方案,预计算每个ITEM的均值/方差后,直接逐行匹配对应ITEM的统计值计算即可,完全避免顺序错位问题。
修正后代码
import pandas as pd import numpy as np import math from scipy.stats import norm # 读取&拆分数据逻辑保持不变 total_data = pd.read_csv('file.csv') present_data = total_data.dropna() future_data = total_data[total_data['Actual Quantity'].isna()] # 新增计算列逻辑保持不变 present_data['Z'] = present_data['Actual Quantity'] / present_data['Scheduled Quantity'] present_data['logZ'] = np.log(present_data['Z']) present_data['logX'] = np.log(present_data['Grade Yields']) # 统一ITEM字段名(确保两个表的ITEM标识对应) present_data['item_id'] = present_data['Item.[Item]'].astype(str) future_data['item_id'] = future_data['Item'].astype(str) # 预计算每个ITEM的统计值,存入字典 item_stats = {} for item_id in present_data['item_id'].unique(): item_data = present_data[present_data['item_id'] == item_id] item_stats[item_id] = { 'mean_yield': item_data['Grade Yields'].mean(), 'mean_logz': item_data['logZ'].mean(), 'var_logx': item_data['logX'].var(), 'var_logz': item_data['logZ'].var() } # 置信度提前定义 CI = confidencelevel['Confidence Level'] # 逐行计算ATP相关指标,自动匹配对应ITEM的统计值 def calc_atp_row(row): cur_stats = item_stats[row['item_id']] sched_qty = row['Sched_Quantity'] projected_prod = cur_stats['mean_yield'] * sched_qty output_atp = cur_stats['mean_yield'] * sched_qty * math.exp( cur_stats['mean_logz'] - (norm.ppf(CI) * math.sqrt(cur_stats['var_logx'] + cur_stats['var_logz'])) ) holdback = projected_prod - output_atp percent_atp = (output_atp / projected_prod) * 100 return pd.Series([projected_prod, output_atp, holdback, percent_atp]) # 赋值结果到future_data future_data[['ProjectedProduction', 'OutputAtp', 'Holdback', 'PercentAtp']] = future_data.apply(calc_atp_row, axis=1)
注意事项
- 请先确认
present_data['Item.[Item]']和future_data['Item']确实是同一个物料编码字段,若字段名本身一致可跳过统一字段名的步骤 - 如果
confidencelevel是单值变量,直接赋值即可,若为Series请确认取到的是单个置信度数值
内容的提问来源于stack exchange,提问作者Iris
相关产品推荐
相关产品推荐

