如何基于两个DataFrame的均值与标准差用For循环生成Python二维数组?
问题描述
我想用numpy的np.random.normal(average, standard deviation, size)函数,基于两个分别存储均值和标准差的DataFrame生成二维数组:
dfa存储不同站点(Maple、Oak)各月份的AvgAdj_Prod(均值)dfs对应存储各站点各月份的StdevAdj_Prod(标准差)
需求是生成8-12月的数据,每个站点生成5行,最终得到10行5列的数组。但当前代码里的rout变量每次循环都会覆盖数据,无法实现追加,求解决办法。
用户原代码:
months = list(range(monthnow, 13)) # months == [8,9,10,11,12] r = [] uniques = df1["site"].unique() # unique number of sites n = 5 ns = list(range(1, n + 1)) # of iterations to calculate (columns) r1 = np.zeros((len(months), n)) # component of np.random.normal(r1,r2,x) r2 = np.zeros((len(months), n)) # component of np.random.normal(r1,r2,x) rout = np.zeros((len(months), n)) # 5 x 5 array of output from np.random.normal() for vals in uniques: for i in months: for k in range(1, n + 1): # print(k) for j in ns: # print(j) r1[k - 1, j - 1] = dfa[(dfa.site == vals)][dfa.month == i]["Adj_Prod"] r2[k - 1][j - 1] = dfs[(dfs.plant_name == vals)][dfs.month == i][ "Adj_Prod" ] rout[k - 1, j - 1] = np.random.normal( r1[k - 1, j - 1], r2[k - 1, j - 1], 1 ) print(rout) r.append(rout)
dfa数据:
month site AvgAdj_Prod 1 Maple 44 2 Maple 48 3 Maple 51 4 Maple 55 5 Maple 62 6 Maple 57 7 Maple 51 8 Maple 44 9 Maple 48 10 Maple 39 11 Maple 38 12 Maple 40 1 Oak 117 2 Oak 129 3 Oak 133 4 Oak 201 5 Oak 206 6 Oak 271 7 Oak 289 8 Oak 221 9 Oak 159 10 Oak 157 11 Oak 140 12 Oak 130
dfs数据:
month site StdevAdj_Prod 1 Maple 12 2 Maple 13 3 Maple 11 4 Maple 10 5 Maple 9 6 Maple 14 7 Maple 7 8 Maple 9 9 Maple 12 10 Maple 14 11 Maple 18 12 Maple 15 1 Oak 25 2 Oak 37 3 Oak 44 4 Oak 39 5 Oak 52 6 Oak 71 7 Oak 49 8 Oak 54 9 Oak 44 10 Oak 69 11 Oak 51 12 Oak 77
问题原因与解决思路
核心问题是:rout在循环外仅初始化一次,处理新站点时会直接覆盖原有数据,而非创建新数组存储当前站点结果。此外原代码嵌套循环冗余,还存在DataFrame索引错误(比如dfs中误用plant_name,实际列名为site)。
解决步骤:
- 处理每个站点时,单独初始化当前站点的结果数组,避免复用同一变量导致覆盖
- 简化循环逻辑:针对目标月份批量生成随机数,无需逐元素赋值
- 用
.loc方法安全筛选DataFrame数据,避免链式索引风险
修正后的代码
import numpy as np import pandas as pd # 目标月份:8-12月 months = list(range(8, 13)) n = 5 # 每个月份生成5个样本 # 站点列表,也可通过dfa["site"].unique()动态获取 sites = dfa["site"].unique() # 存储各站点结果的列表 site_results = [] for site in sites: # 筛选当前站点8-12月的均值和标准差 site_avg = dfa.loc[(dfa["site"] == site) & (dfa["month"].isin(months)), "AvgAdj_Prod"].values site_std = dfs.loc[(dfs["site"] == site) & (dfs["month"].isin(months)), "StdevAdj_Prod"].values # 批量生成随机数:形状为(5,5)(5个月 × 5个样本) # 通过[:, np.newaxis]将一维数组转为二维,适配批量生成逻辑 current_rout = np.random.normal(site_avg[:, np.newaxis], site_std[:, np.newaxis], size=(len(months), n)) # 将当前站点结果加入列表 site_results.append(current_rout) # 垂直拼接两个站点的结果,得到10行5列的最终数组 final_array = np.vstack(site_results) print(final_array.shape) # 输出(10, 5)
内容的提问来源于stack exchange,提问作者user2100039
相关产品推荐
相关产品推荐

