来自不同概率列表的 Python 加权随机选择,比较来自 CSV 的两个 Pandas DataFrame

问题描述 投票:0回答:2

Python初学者,看这里。我正在尝试使用 pandas DataFrame(从 CSV 创建)并使用加权随机选择从另一个 DataFrame(从 CSV 创建)中进行选择。我有两个 pandas DataFrames,读起来像这样:

代码的加权百分比:

部分 代码 Final_Per
B1 800 5%
B1 801 65%
B1 802 30%
B2 900 30%
B2 901 70%
B3 600 50%
B3 601 50%

输入 pandas DataFrame 以运行加权百分比:

部分 号码
B1 14
B2 25
B3 12

这些只是我的表格的示例,而不是整个表格本身。我需要做的是将这些加权概率存储在字典、列表或 pandas 数据帧中(不确定什么是最好的)——然后将我上面的第二个表应用到 'Final_Per' % 到 'NUMBER' 列并输出结果。所以 B1 的结果将是 14 个值,5% 是代码 800,65% 是代码 801,30% 是代码 802。目前,这些表是 CSV,我正在把它们变成 pandas 数据帧,并试图从中吸取一些经验教训文章https://pynative.com/python-weighted-random-choices-with-probability/ 没有成功。有人对如何正确处理这个问题有建议吗?谢谢。

python pandas random probability weighted
2个回答
0
投票

如果您将 CSV 数据重塑为:

SECTION_COUNTS = {
    "B1": 14,
    "B2": 25,
    "B3": 12,
}

SECTION_DISTRIBUTIONS = {
    "B1": [
        {"code": 800, "from": 1, "to": 5},
        {"code": 801, "from": 6, "to": 70},
        {"code": 802, "from": 71, "to": 100}
    ],
    "B2": [
        {"code": 900, "from": 1, "to": 70},
        {"code": 901, "from": 71, "to": 100}
    ],
    "B3": [
        {"code": 600, "from": 1, "to": 50},
        {"code": 601, "from": 51, "to": 100}
    ]
}

我想你寻求的答案可能是:

import random

results = {}
for section_id, count in SECTION_COUNTS.items():
    for _ in range(count):
        code = next(
            row["code"]
            for row
            in SECTION_DISTRIBUTIONS[section_id]
            if row["from"] <= random.randint(1, 100) <= row["to"]
        )
        results.setdefault(section_id, []).append(code)
print(results)

结果是这样的:

{
    'B1': [801, 801, 802, 801, 801, 802, 800, 802, 802, 801, 802, 801, 800, 801],
    'B2': [900, 900, 900, 900, 900, 901, 900, 900, 901, 900, 900, 901, 901, 900, 900, 900, 901, 900, 901, 900, 900, 901, 900, 901, 900],
    'B3': [601, 601, 600, 600, 600, 601, 601, 601, 600, 601, 600, 600]
}

0
投票

另一种方法是将 csv 文件加载到数据框中,合并它们并使用

.apply
.

from numpy.random import choice

df1 = pd.read_csv(/path/to/csv1)
df2 = pd.read_csv(/path/to/csv2)

def calculate_distribution(mini_df): 
    prob = mini_df.prob.str[:-1].astype(float) / 100
    return choice(mini_df.code.values, mini_df.n.values[0], p=prob)

distributions = df1.merge(df2, on='section').groupby('section').apply(calculate_distribution)
print(distributions)
© www.soinside.com 2019 - 2024. All rights reserved.