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

生成带列上下限且行和为100的随机DataFrame遇求和精度问题

问题:生成满足列上下限且行和接近100的DataFrame

我需要生成一个填充随机浮点数的DataFrame,要求:

  • 每列的值由给定的元组列表定义上下限
  • 每行的求和结果需落在99.9到100.1之间(公差0.1)

但当前实现的部分行和达不到99.99及以上,代码如下:

import pandas as pd
import numpy as np

num_rows = 150
num_cols = 15

bounds = [(0, 20), (0, 10), (0, 15), (0, 5), (0, 10), (0, 5), (0, 20), (0, 10), (0, 10), (0, 5), (0, 5), (0, 10), (0, 5), (0, 10), (0, 10)]

tolerance = 0.1

df = pd.DataFrame(np.zeros((num_rows, num_cols)))

num_generated_rows = 0
while num_generated_rows < num_rows:
    for row in range(num_generated_rows, num_rows):
        row_sum = 0
        for col in range(num_cols):
            lower, upper = bounds[col]
            remaining_cols = num_cols - col - 1
            remaining_sum = 100 - row_sum
            if remaining_cols > 0:
                min_possible_value = max(0, remaining_sum - remaining_cols * upper)
                max_possible_value = min(upper, remaining_sum - remaining_cols * lower)
            else:
                min_possible_value = max(0, 100 - row_sum - upper)
                max_possible_value = min(upper, 100 - row_sum - lower)
            value = np.random.uniform(min_possible_value, max_possible_value)
            df.iloc[row, col] = value
            row_sum += value
        
        # Check if the row sum is within the defined tolerance
        if abs(row_sum - 100) <= tolerance:
            num_generated_rows += 1
            break
        
        # Stop generating rows if we've reached the desired number
        if num_generated_rows == num_rows:
            break

df = df.sample(frac=1).reset_index(drop=True)

问题分析

  1. 最后一列计算逻辑错误:处理最后一列(remaining_cols=0)时,原代码的取值范围计算混乱,导致最后一列无法精准将行和拉到100附近。
  2. 无有效性校验:前面列的随机取值可能导致剩余总和无法满足后续列的上下限约束,此时继续生成会得到无效行,但原代码没有提前终止并重置该行的逻辑。

修正后的代码

import pandas as pd
import numpy as np

num_rows = 150
num_cols = 15

bounds = [(0, 20), (0, 10), (0, 15), (0, 5), (0, 10), (0, 5), (0, 20), (0, 10), (0, 10), (0, 5), (0, 5), (0, 10), (0, 5), (0, 10), (0, 10)]

tolerance = 0.1
df = pd.DataFrame(np.zeros((num_rows, num_cols)))
num_generated_rows = 0

while num_generated_rows < num_rows:
    row_sum = 0
    valid_row = True
    row_data = []
    for col in range(num_cols):
        lower, upper = bounds[col]
        remaining_cols = num_cols - col - 1
        
        # 计算当前列的合法取值范围:兼顾自身上下限和剩余列的约束
        min_val = max(lower, 100 - row_sum - remaining_cols * upper)
        max_val = min(upper, 100 - row_sum - remaining_cols * lower)
        
        # 若当前列无合法取值,直接放弃该行,重新生成
        if min_val > max_val:
            valid_row = False
            break
        
        # 最后一列直接取刚好凑够100的值(钳位到列的上下限内)
        if remaining_cols == 0:
            val = 100 - row_sum
            val = max(lower, min(upper, val))
        else:
            val = np.random.uniform(min_val, max_val)
        
        row_data.append(val)
        row_sum += val
    
    # 验证行和符合要求后,存入DataFrame
    if valid_row and abs(row_sum - 100) <= tolerance:
        df.iloc[num_generated_rows] = row_data
        num_generated_rows += 1

# 打乱行顺序
df = df.sample(frac=1).reset_index(drop=True)

# 可选:验证行和分布
print("行和统计信息:")
print(df.sum(axis=1).describe())

修正说明

  • 精准控制最后一列:最后一列不再随机取值,直接计算为100 - row_sum并钳位到列的上下限内,确保行和尽可能接近100。
  • 提前终止无效行生成:当某一列无合法取值范围时,直接放弃当前行的生成,避免无效计算。
  • 优化取值范围计算:每列的最小/最大值同时考虑自身上下限和剩余列的约束,确保后续列有足够空间满足要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:38:19