如何确保 np.random.choice 中的一对项目不会一起出现在一个循环中?
How to make sure a pair of items in np.random.choice don't appear together in a loop?
我目前正在尝试 运行 蒙特卡洛模拟而不用替换,使用 np.random.choice,但是列表中的某些项目不能一起出现。例如,如果我有一个包含五个项目的列表:RO、MI、VE、NA、SI,并且每个循环产生一组四个项目,RO 可以与 VE、MI 或 NA 一起出现,但不能与 SI 一起出现,在每次迭代中。
所以像这样的循环:[RO,MI,VE,NA] 是正确的
但不是:[RO,MI,SI,NA],因为 SI 出现在与 RO 相同的组中。
这是我目前使用的代码(产生了不正确的分组):
np.random.seed(42)
portfolio=[]
for i in range(0,10000):
port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
portfolio.append(port_gar)
print(portfolio)
我不知道该怎么做,我们将不胜感激。谢谢!
在不了解更多关于哪些城市可以出现在列表中的限制的情况下,最简单的解决方案可能是随机生成城市,直到您拥有足够多的有效城市。例如:
def check_valid(port_gar):
is_valid = True
if 'RO' in port_gar:
is_valid = is_valid and ('NA' not in port_gar and 'VE' not in port_gar)
if 'NA' in port_gar:
is_valid = is_valid and 'VE' not in port_gar
# Add other checks for constraints here
return is_valid
portfolio = []
while len(portfolio) < 10000:
port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
if check_valid(port_gar):
portfolio.append(port_gar)
print(portfolio)
这绝对不是最高效的实现方式,但如果样本数量相对较少(本例中为 10000)且城市数量较多,那么性能应该没问题。
我提出了两个解决方案,它们都使用了标准库中的 random
模块。我推荐这种方法而不是使用 numpy,因为你不能以任何方式在这里真正利用 numpy,特别是因为你甚至没有在最后得到一个 numpy 数组(你只是 使用 numpy 生成随机数)。
解决方案 1:每个样本都有恰好一个城市来自“独家城市”组
您可以做的是将表现不佳的城市与其他城市分开:
import random
random.seed(42)
n = 10 # whatever total number of items you want per sample
num_samples = 10000 # total number of samples
free_cities = [...] # all cities in this group play nicely together
exclusive_cities = [...] # cities in this group cannot be grouped in a sample, so we will only ever choose one city at a time from this group
portfolio = []
for _ in range(num_samples):
free_sample = random.sample(free_cities, k=(n-1))
exclusive_sample = random.sample(exclusive_cities, k=1)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
这是一个人为的例子:
n = 6
num_samples = 10
free_cities = ["AW", "JB", "EX", "HZ", "MZ", "XQ", "KA", "MW", "WZ", "UD"]
exclusive_cities = ["RO", "VE", "SI", "NA"]
portfolio = []
for _ in range(num_samples):
free_sample = random.sample(free_cities, k=(n-1))
exclusive_sample = random.sample(exclusive_cities, k=1)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
输出:
>>> portfolio
[['AW', 'EX', 'WZ', 'RO', 'MZ', 'JB'],
['RO', 'MZ', 'KA', 'WZ', 'XQ', 'EX'],
['AW', 'MW', 'VE', 'JB', 'WZ', 'XQ'],
['NA', 'WZ', 'JB', 'MW', 'EX', 'MZ'],
['SI', 'UD', 'AW', 'JB', 'WZ', 'MW'],
['MZ', 'JB', 'UD', 'VE', 'WZ', 'HZ'],
['NA', 'KA', 'UD', 'AW', 'MW', 'WZ'],
['JB', 'NA', 'UD', 'KA', 'WZ', 'MW'],
['MZ', 'RO', 'JB', 'HZ', 'AW', 'XQ'],
['WZ', 'HZ', 'UD', 'JB', 'VE', 'XQ']]
现在需要注意的是,这将保证每个样本都只有 exclusive_cities
组中的一个城市:
for sample in portfolio:
print(set(sample) & set(exclusive_cities))
输出:
# Every sample has one item from the exclusive_cities group
{'RO'}
{'RO'}
{'VE'}
{'NA'}
{'SI'}
{'VE'}
{'NA'}
{'NA'}
{'RO'}
{'VE'}
解决方案 2:每个样本最多 一个 个来自“独家城市”组的城市
如果这不是您想要的行为,您可以使用额外的“掷硬币”来确定给定示例中是否出现 1 或 0 个排他性城市,并对上述逻辑稍作修改:
n = 6
num_samples = 10
portfolio = []
for _ in range(num_samples):
include = random.choice((0, 1))
free_sample = random.sample(free_cities, k=(n - include))
exclusive_sample = random.sample(exclusive_cities, k=include)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
现在您的样本可能包含也可能不包含一个专属城市,但仍然只有一个最大值:
# An empty set means an exclusive city isn't present in that sample
set()
set()
{'SI'}
{'NA'}
set()
{'RO'}
{'SI'}
{'VE'}
set()
{'RO'}
我目前正在尝试 运行 蒙特卡洛模拟而不用替换,使用 np.random.choice,但是列表中的某些项目不能一起出现。例如,如果我有一个包含五个项目的列表:RO、MI、VE、NA、SI,并且每个循环产生一组四个项目,RO 可以与 VE、MI 或 NA 一起出现,但不能与 SI 一起出现,在每次迭代中。 所以像这样的循环:[RO,MI,VE,NA] 是正确的 但不是:[RO,MI,SI,NA],因为 SI 出现在与 RO 相同的组中。 这是我目前使用的代码(产生了不正确的分组):
np.random.seed(42)
portfolio=[]
for i in range(0,10000):
port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
portfolio.append(port_gar)
print(portfolio)
我不知道该怎么做,我们将不胜感激。谢谢!
在不了解更多关于哪些城市可以出现在列表中的限制的情况下,最简单的解决方案可能是随机生成城市,直到您拥有足够多的有效城市。例如:
def check_valid(port_gar):
is_valid = True
if 'RO' in port_gar:
is_valid = is_valid and ('NA' not in port_gar and 'VE' not in port_gar)
if 'NA' in port_gar:
is_valid = is_valid and 'VE' not in port_gar
# Add other checks for constraints here
return is_valid
portfolio = []
while len(portfolio) < 10000:
port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
if check_valid(port_gar):
portfolio.append(port_gar)
print(portfolio)
这绝对不是最高效的实现方式,但如果样本数量相对较少(本例中为 10000)且城市数量较多,那么性能应该没问题。
我提出了两个解决方案,它们都使用了标准库中的 random
模块。我推荐这种方法而不是使用 numpy,因为你不能以任何方式在这里真正利用 numpy,特别是因为你甚至没有在最后得到一个 numpy 数组(你只是 使用 numpy 生成随机数)。
解决方案 1:每个样本都有恰好一个城市来自“独家城市”组
您可以做的是将表现不佳的城市与其他城市分开:
import random
random.seed(42)
n = 10 # whatever total number of items you want per sample
num_samples = 10000 # total number of samples
free_cities = [...] # all cities in this group play nicely together
exclusive_cities = [...] # cities in this group cannot be grouped in a sample, so we will only ever choose one city at a time from this group
portfolio = []
for _ in range(num_samples):
free_sample = random.sample(free_cities, k=(n-1))
exclusive_sample = random.sample(exclusive_cities, k=1)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
这是一个人为的例子:
n = 6
num_samples = 10
free_cities = ["AW", "JB", "EX", "HZ", "MZ", "XQ", "KA", "MW", "WZ", "UD"]
exclusive_cities = ["RO", "VE", "SI", "NA"]
portfolio = []
for _ in range(num_samples):
free_sample = random.sample(free_cities, k=(n-1))
exclusive_sample = random.sample(exclusive_cities, k=1)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
输出:
>>> portfolio
[['AW', 'EX', 'WZ', 'RO', 'MZ', 'JB'],
['RO', 'MZ', 'KA', 'WZ', 'XQ', 'EX'],
['AW', 'MW', 'VE', 'JB', 'WZ', 'XQ'],
['NA', 'WZ', 'JB', 'MW', 'EX', 'MZ'],
['SI', 'UD', 'AW', 'JB', 'WZ', 'MW'],
['MZ', 'JB', 'UD', 'VE', 'WZ', 'HZ'],
['NA', 'KA', 'UD', 'AW', 'MW', 'WZ'],
['JB', 'NA', 'UD', 'KA', 'WZ', 'MW'],
['MZ', 'RO', 'JB', 'HZ', 'AW', 'XQ'],
['WZ', 'HZ', 'UD', 'JB', 'VE', 'XQ']]
现在需要注意的是,这将保证每个样本都只有 exclusive_cities
组中的一个城市:
for sample in portfolio:
print(set(sample) & set(exclusive_cities))
输出:
# Every sample has one item from the exclusive_cities group
{'RO'}
{'RO'}
{'VE'}
{'NA'}
{'SI'}
{'VE'}
{'NA'}
{'NA'}
{'RO'}
{'VE'}
解决方案 2:每个样本最多 一个 个来自“独家城市”组的城市
如果这不是您想要的行为,您可以使用额外的“掷硬币”来确定给定示例中是否出现 1 或 0 个排他性城市,并对上述逻辑稍作修改:
n = 6
num_samples = 10
portfolio = []
for _ in range(num_samples):
include = random.choice((0, 1))
free_sample = random.sample(free_cities, k=(n - include))
exclusive_sample = random.sample(exclusive_cities, k=include)
portfolio.append(random.sample(free_sample + exclusive_sample, k=n))
现在您的样本可能包含也可能不包含一个专属城市,但仍然只有一个最大值:
# An empty set means an exclusive city isn't present in that sample
set()
set()
{'SI'}
{'NA'}
set()
{'RO'}
{'SI'}
{'VE'}
set()
{'RO'}