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

Scipy中差分进化(DE)替代暴力寻优报错问题求助

Why brute Works but differential_evolution Throws an Error?

Let's break down the issue and fix it step by step:

Root Cause

Your objective function fun returns a pandas Series instead of a scalar value, which differential_evolution can't handle.

Look at the line where you calculate p_hat:

p_hat = df_Res.sum() / len(df_Res.index)

df_Res.sum() returns a Series (since df_Res is a single-column DataFrame), so dividing by the length still leaves you with a Series. scipy.optimize.brute is lenient enough to implicitly use the underlying scalar value of the Series, but differential_evolution strictly requires a single numerical value to compute fitness for its iterative optimization process. This mismatch is why you get the ambiguous truth value error— the optimizer tries to evaluate the Series as a boolean, which pandas doesn't allow.

Fix 1: Return a Scalar Instead of a Series

Modify the return line in your fun function to extract the scalar value from the Series. Use .item() (the cleanest way for single-value Series) or .iloc[0]:

def fun(z, *params):
    A,B,C = z
    df_1, df_2 = params  # Explicitly unpack params for clarity
    
    # Calculate score without modifying original df_2 (see Fix 2 below)
    df_2_copy = df_2.copy()
    df_2_copy['S'] = df_2_copy['X']*A + df_2_copy['Y']*B + df_2_copy['Z']*C
    
    # Top score logic
    df_Sort = df_2_copy.sort_values(['S', 'X', 'M'], ascending=[False, True, True])
    df_O = df_Sort.set_index('O')
    M_Top = df_O[~df_O.index.duplicated(keep='first')].M
    M_Top = M_Top.sort_index()
    
    # Compare to df_1
    df_1_R = df_1_M.reindex(M_Top.index)
    T_N_T = M_Top == df_1_R
    
    # Calculate p_hat and return scalar
    df_Res = pd.DataFrame({'it_is':T_N_T})
    p_hat = df_Res.sum() / len(df_Res.index)
    return -p_hat.item()  # Convert Series to scalar here

Fix 2: Avoid Modifying the Original df_2

Your original function modifies the input df_2 by adding an 'S' column. This can cause unexpected side effects in iterative optimizers like differential_evolution, which call the function hundreds of times. The fix above creates a copy of df_2 first to isolate calculations from the original data.

Test the Fixed Code

Now run differential_evolution again—it should work correctly:

from scipy.optimize import differential_evolution
import pandas as pd

# Re-initialize data and setup df_1_M
df_1 = pd.DataFrame({'O' : [1,2,3], 'M' : [2,8,3]})
df_2 = pd.DataFrame({'O' : [1,1,1, 2,2,2, 3,3,3], 'M' : [9,2,4, 6,7,8, 5,3,4], 'X' : [2,4,6, 4,8,7, 3,1,9], 'Y' : [3,6,1, 4,6,5, 1,0,7], 'Z' : [2,4,8, 3,5,4, 7,5,1]})

df_1 = df_1.set_index('O')
df_1_M = df_1.M.sort_index()

# Bounds
min_ = -2
max_ = 2
bounds = [(min_, max_)] * 3
params = (df_1, df_2)

# Run differential evolution
DE = differential_evolution(fun, bounds, args=params)

print('Global maximum ', DE.x)
print('Function value at global maximum ',-DE.fun)

You'll get results similar to the brute method, but with drastically faster execution for higher dimensions or finer resolutions.

内容的提问来源于stack exchange,提问作者R. Cox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:42:49