You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于两个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:27:28