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

Python DataFrame列优化:生成满足约束条件的第三列方案咨询

生成满足区间与总和约束的DataFrame列解决方案

核心逻辑

首先必须确认目标总和落在所有行min值的总和与所有行max值的总和之间,否则无解。若可行,优先给每行分配基准值(比如min值),再将剩余需要补足的量按每行的可分配空间(max-min)均匀分摊;如果需要更严谨的“均匀”(比如最小化各值与理论均值的偏差),可以用线性规划求解。

推荐库

  • pandas:处理DataFrame的基础工具,必备
  • scipy.optimize:用于线性规划求解,适合需要严谨约束的场景
  • cvxpy(可选):如果涉及二次优化(比如最小化方差),这个库更易用

实现示例

方法1:贪心均匀分配(简单高效,适合大多数场景)

import pandas as pd

# 示例数据
df = pd.DataFrame({
    'min number': [1, 2, 3, 4],
    'max number': [5, 6, 7, 8]
})
target_sum = 18

# 校验目标总和是否在可行范围内
min_total = df['min number'].sum()
max_total = df['max number'].sum()
if not min_total <= target_sum <= max_total:
    raise ValueError(f"目标总和必须处于 [{min_total}, {max_total}] 区间内")

# 初始分配最小值,计算剩余待分配量
df['result'] = df['min number']
remaining = target_sum - min_total

# 计算每行可额外分配的空间
df['available_space'] = df['max number'] - df['min number']

# 循环均匀分配剩余量
while remaining > 1e-9:  # 处理浮点精度问题
    # 计算当前剩余量的平均分配值
    avg_add = remaining / len(df)
    # 给每行分配不超过其可用空间的量
    add_amount = df['available_space'].clip(upper=avg_add)
    # 更新结果、剩余量和可用空间
    df['result'] += add_amount
    remaining -= add_amount.sum()
    df['available_space'] -= add_amount
    # 过滤掉已无分配空间的行
    df = df[df['available_space'] > 1e-9].copy()

# 可选:保留两位小数
df['result'] = df['result'].round(2)

方法2:线性规划求解(严谨优化,最小化偏差)

如果需要让生成的列尽可能接近理论均值(target_sum/行数),可以用线性规划最小化各值与均值的偏差:

from scipy.optimize import linprog
import pandas as pd

df = pd.DataFrame({
    'min number': [1, 2, 3, 4],
    'max number': [5, 6, 7, 8]
})
target_sum = 18
n_rows = len(df)
target_avg = target_sum / n_rows

# 目标函数:最小化各值与均值的绝对偏差之和(转化为线性约束)
# 引入辅助变量s_i = |x_i - target_avg|,目标是sum(s_i)最小
c = [0]*n_rows + [1]*n_rows  # x_i的系数为0,s_i的系数为1

# 约束条件:
# 1. sum(x_i) = target_sum
A_eq = [[1]*n_rows + [0]*n_rows]
b_eq = [target_sum]

# 2. x_i - target_avg <= s_i → x_i - s_i <= target_avg
# 3. target_avg - x_i <= s_i → -x_i - s_i <= -target_avg
A_ub = []
b_ub = []
for i in range(n_rows):
    row1 = [0]*n_rows + [0]*n_rows
    row1[i] = 1
    row1[n_rows + i] = -1
    A_ub.append(row1)
    b_ub.append(target_avg)
    
    row2 = [0]*n_rows + [0]*n_rows
    row2[i] = -1
    row2[n_rows + i] = -1
    A_ub.append(row2)
    b_ub.append(-target_avg)

# 变量边界:min_i <= x_i <= max_i;s_i >= 0
bounds = []
for min_val, max_val in zip(df['min number'], df['max number']):
    bounds.append((min_val, max_val))
for _ in range(n_rows):
    bounds.append((0, None))

# 求解线性规划
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='highs')

if res.success:
    df['result'] = res.x[:n_rows].round(2)
else:
    raise ValueError("无法找到满足所有约束的解")

学习资料推荐

  • YouTube视频系列:
    • Python Data Science Tutorials:涵盖pandas核心操作与数据处理技巧,帮你快速掌握DataFrame的各类操作
    • Optimization with Python:系统讲解Python中的优化工具(包括scipy、cvxpy),从基础线性规划到复杂优化问题都有实操案例
    • Advanced Pandas Tutorials:深入讲解pandas的高级功能,适合处理这类带约束的数据列生成场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:55:28