生成和为1的权重计算加权平均遇0值及百万次循环求最小极差求助
问题1:F(x)全部为0.0的原因
你当前的代码里,生成的权重ar是索引为0-5的Series,但CSV数据的列名是A、B、C、D、E、F、F(x),列名完全不匹配,导致df.mul(ar)时没有对应列可相乘,结果全为NaN(或被默认填充为0),求和后自然得到0.0。
解决办法是提取CSV中用于计算的6个数值列,直接按位置和权重相乘(不依赖列名匹配):
import numpy as np import pandas as pd # 读取CSV,若第一列是行号,设置index_col=0避免列名混乱 df = pd.read_csv('weit.csv', index_col=0) # 提取6个数值列:排除最后一列F(x),剩下的就是目标数据列 data_cols = df.columns[:-1] # 生成权重:直接得到长度为6的数组,无需转DataFrame weights = np.random.dirichlet(np.ones(6), size=1)[0] # 计算加权平均 df['F(x)'] = df[data_cols].mul(weights, axis=1).sum(axis=1) # 验证结果 print(df['F(x)']) current_range = df['F(x)'].max() - df['F(x)'].min() print(f"当前极差:{current_range}")
问题2:实现百万次循环找到最小极差的权重集
要完成百万次迭代,我们需要初始化存储最小极差和对应权重的变量,循环生成权重、计算F(x)和极差,每次比较并更新最小值。为提升效率,用numpy向量化操作替代pandas的逐行计算:
import numpy as np import pandas as pd # 1. 读取并预处理数据 df = pd.read_csv('weit.csv', index_col=0) data_cols = df.columns[:-1] data = df[data_cols].values # 转numpy数组,大幅加快计算速度 # 2. 初始化最小极差和最优权重 min_range = float('inf') best_weights = None # 3. 百万次循环迭代 n_iterations = 1000000 for i in range(n_iterations): # 生成和为1的随机权重 weights = np.random.dirichlet(np.ones(6), size=1)[0] # 矩阵乘法计算加权平均,等价于每行与权重相乘后求和 fx = data @ weights # 计算当前极差 current_range = fx.max() - fx.min() # 更新最小极差和最优权重 if current_range < min_range: min_range = current_range best_weights = weights.copy() # 复制数组,避免后续循环修改引用值 # 每10万次打印进度,监控运行状态 if (i + 1) % 100000 == 0: print(f"完成 {i+1}/{n_iterations} 次迭代,当前最小极差: {min_range:.4f}") # 输出最终结果 print("\n=== 最终结果 ===") print(f"最小极差: {min_range:.4f}") print(f"对应的权重集: {best_weights}") # 将最优权重的F(x)存入原DataFrame df['F(x)_best'] = data @ best_weights print("\n最优权重下的F(x)列:") print(df['F(x)_best'])
代码优化说明:
- 用numpy数组存储数据,矩阵乘法
data @ weights比pandas的mul+sum效率高数倍,适合百万次循环; - 避免不必要的DataFrame转换,循环中仅操作轻量的numpy数组;
- 加入进度打印,防止程序假死;
- 用
weights.copy()避免后续循环修改最优权重的引用值。
额外注意事项
- 确保CSV格式正确:表头列数与数据列数一致,若第一列是行号,务必设置
index_col=0; - 百万次循环在普通电脑上约需几分钟,若需更快可尝试多进程优化,但上述代码已足够高效;
- Dirichlet分布天然生成和为1的随机数,非常适合权重生成,你的初始选择是正确的。
内容的提问来源于stack exchange,提问作者winfred adrah
相关产品推荐
相关产品推荐

