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

使用numpy与pandas从DF随机选择,10万次后分布不符合预期

D&D施法概率脚本问题分析与优化方案

问题原因

当前方案出现概率偏差的核心原因无非两种:

  1. 行数计算不精准:如果原法术DataFrame的行数是奇数,你没办法精准追加“原DF一半”的行数(比如原DF有95行,只能加47或48行),导致三类结果的总行数比例偏离预期的50/25/25,采样概率自然跟着偏差。
  2. 统计逻辑出错:要是你统计结果时,把“随机采样到当前指定法术”的情况从“随机法术”类别里拆分出来,会直接拉低“随机法术”的占比,同时让“原法术生效”的统计值混入随机命中的情况,出现数据偏差。

另外,10万次采样出现3%左右的偏差,绝对不是随机误差,肯定是代码里的行数计算或者统计逻辑出了问题,比如你可能误把追加行数设成了原DF的其他比例,而非准确的一半。

优化方案

没必要修改原DataFrame去追加大量重复行,直接用下面两种方法就能实现精准概率,逻辑更清晰,效率也更高:

方案一:分阶段随机选择(推荐)

先按概率确定事件类型,再执行对应逻辑,完全贴合你的需求:

import random
import pandas as pd

# 示例原法术列表
spell_df = pd.DataFrame({"spell_name": ["火球术", "治愈术", "闪电术", "隐身术"]})
# 当前施法者要放的目标法术
target_spell = "火球术"

def cast_spell():
    # 第一步:按设定概率选事件类型
    event = random.choices(
        ["随机法术", "原法术生效", "无效果"],
        weights=[0.5, 0.25, 0.25],
        k=1
    )[0]
    
    if event == "随机法术":
        # 从原法术里随机挑一个
        return spell_df.sample(n=1).iloc[0]["spell_name"]
    elif event == "原法术生效":
        return target_spell
    else:
        return "无效果"

# 10万次测试示例
results = [cast_spell() for _ in range(100000)]
random_rate = sum(1 for res in results if res in spell_df["spell_name"].values and res != target_spell) / 100000
original_rate = sum(1 for res in results if res == target_spell) / 100000
nothing_rate = sum(1 for res in results if res == "无效果") / 100000

print(f"随机法术占比:{random_rate:.2%}")
print(f"原法术生效占比:{original_rate:.2%}")
print(f"无效果占比:{nothing_rate:.2%}")

方案二:带权重直接采样

把所有可能结果整合到一个列表,通过权重分配实现精准概率:

import random
import pandas as pd

spell_df = pd.DataFrame({"spell_name": ["火球术", "治愈术", "闪电术", "隐身术"]})
target_spell = "火球术"

# 构建所有可选结果
all_options = spell_df["spell_name"].tolist() + [target_spell, "无效果"]
# 分配权重:随机法术总权重0.5,分摊到每个法术;原法术和无效果各占0.25
weights = [0.5 / len(spell_df)] * len(spell_df) + [0.25, 0.25]

def cast_spell():
    return random.choices(all_options, weights=weights, k=1)[0]

# 测试逻辑同上,此处省略

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:45:55