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

Scipy优化中使用数组型参数时如何避免序列赋值错误?

解决Scipy Minimize中数组型参数的优化问题

这个错误的核心原因很明确:Scipy的minimize函数要求初始参数必须是一维扁平数组,它无法直接处理包含嵌套数组的参数列表。你之前把数组M和theta直接放进params0里,导致numpy在尝试将其转换为数组时遇到了嵌套序列,触发了ValueError。

下面是具体的解决方案,我们只需要做两步:将所有参数扁平化为一维数组,然后在目标函数里重新拆分回原来的标量和数组结构。

修改后的完整代码

import pandas as pd
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import minimize

def f(yvec, t, a, b, c, d, M, theta):
    # the system of ODEs to be solved
    x, y = yvec
    dydt = [
        a*x - b*y**2 + 1,
        -c*x - d*x*y + np.sum(M * np.cos(theta*t))
    ]
    return dydt

ni = 3  # the number of periodic forcing functions to add to the DE system
M_initial = 0.56*np.random.rand(ni)  # the initial amplitudes of forcing functions
theta_initial = np.pi/6*np.arange(ni)  # the initial coefficients of the forcing functions

# 1. 将所有参数扁平化为一维数组:标量 + 数组元素依次排列
params0_flat = np.concatenate([
    [0.75, 0.23, 1.0, 0.2],  # 标量参数a,b,c,d
    M_initial.flatten(),      # M的元素
    theta_initial.flatten()   # theta的元素
])

# grabbing the data to be used later
data = pd.read_csv('data.csv')
y_data = data['Y']
N = y_data.shape[0] #20
t = np.linspace(0, N, N) # array of t values to integrate over
yvec0 = [0.3, 0.34] # initial conditions for x and y respectively

def norm_residual(params, *args):
    """ Computes the L^2 norm of the residual of y and the data (y as defined above).
    Input:
        params = 一维扁平数组,包含所有优化参数
        args = other arguments to pass into the function f or to use to compute the residual.
    Output:
        err = L^2 error of the solution vector (scalar).
    """
    data, yvec0, t = args
    ni = 3  # 和之前定义的ni一致
    
    # 2. 将扁平参数拆分回原来的标量和数组
    a, b, c, d = params[:4]
    M = params[4:4+ni]
    theta = params[4+ni:]
    
    sol = odeint(f, yvec0, t, args=(a, b, c, d, M, theta))
    x = sol[:, 0]; y = sol[:, 1]
    res = data - y
    err = np.linalg.norm(res, 2)
    return err

# 现在可以正常调用minimize了
p_min = minimize(norm_residual, params0_flat, args=(y_data, yvec0, t))
print(p_min)

# 如果需要提取优化后的M和theta:
optimized_params = p_min.x
optimized_M = optimized_params[4:4+ni]
optimized_theta = optimized_params[4+ni:]
print("优化后的M:", optimized_M)
print("优化后的theta:", optimized_theta)

关键说明

  • 参数扁平化:我们用np.concatenate把标量列表和数组的扁平版本合并成一个一维数组,这样minimize就能正确识别所有参数为连续的优化变量。
  • 参数拆分:在目标函数内部,我们根据参数的原始结构,从扁平数组中切片拆分出标量a,b,c,d和数组M,theta,完全不影响原ODE函数的逻辑。
  • 扩展性:如果后续需要调整ni的数值,只需要修改ni变量,切片逻辑会自动适配,不需要硬编码索引。

这个方法不仅解决了你的错误,还完全保留了让minimize自动优化数组型参数的需求,是处理这类问题的标准做法。

内容的提问来源于stack exchange,提问作者BRz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:31:16