我正在尝试使用其他三个列表(高、中和低)中的值创建一个列表。新列表应该根据 probability_array 进行评估,它应该从哪个列表中选择一个随机值。新列表应该类似于播放列表:在随机选择的值被选择两次(从高、中或低)之前,特定列表的所有其他值(高、中或低)必须在新生成的列表中。
任何想法,我如何才能实现这一点。到目前为止我的代码:
import numpy as np
array_length = 30
high = [(1, 2), 3, 4, 5, 6, (7, 8, 9)]
medium = [10, 11, (12, 13), 14]
low = [100, 101, 102, (103, 104)]
probability_array = np.random.choice(
['High', 'Medium', 'Low',],
array_length,
p=[4/7, 2/7, 1/7]
)
# i. e.
"""
['Low' 'High' 'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'Medium'
'High' 'High' 'Medium' 'Medium' 'High' 'High' 'Medium' 'Medium' 'High'
'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'High' 'High' 'Low'
'High']
"""
# new list should look like:
"""
[102, (1, 2), 4, (7, 8, 9), 3, 6, 14, ...]
"""
谢谢
最佳答案
np.random.choice
有一个选项可以指定项目被选中的概率。您可以用它构建一个 high, medium, low
列表,并将其输入另一个循环以正确构建您的播放列表
- 根据 roganjosh 的建议,我还删除了同一项目背靠背出现的能力
import numpy as np
import random
import collections
playlist_length = 30
# key is the match strength (ie. high, medium, low)
matches = {
'high' : {
'items' : [(1, 2), 3, 4, 5, 6, (7, 8, 9)],
'prob' : 4/7
},
'medium' : {
'items' : [10, 11, (12, 13), 14],
'prob' : 2/7
},
'low' : {
'items' : [100, 101, 102, (103, 104)],
'prob' : 1/7
}
}
# create two lists:
# a is a list of match strengths
# p is the desired probability of an item from that match strength occuring
a, p = zip(*[(match, matches[match]['prob']) for match in matches])
# build a list of match strengths, with our chosen size and probability
results = np.random.choice(a=a, p=p, size=playlist_length)
# build our playlist
playlist = []
last_item = None
for match_strength in results:
# count all the items currently in playlist (a bit inefficient, probably don't have to recreate the Counter obj everytime)
count_playlist = collections.Counter(playlist)
# filter items of the given match strength, leaving out those that are at the current max
items = matches[match_strength]['items']
max_count = max([count_playlist[item] for item in items])
filtered = list(filter(lambda item: count_playlist[item] < max_count, items))
# if all items have the same count, reset the filtered list to be any item
if not len(filtered):
filtered = items
# drop last item so that it does not repeat
if last_item and last_item in filtered and len(filtered) > 1:
filtered.remove(last_item)
# add one from filtered items to playlist
new_item = random.choice(filtered)
playlist.append(new_item)
last_item = new_item
print(collections.Counter(results))
print(playlist)
输出:
计数器显示不同的匹配强度出现在可接受的频率 Counter({'high': 19, 'medium': 10, 'low': 1})
播放列表是
[(1, 2), 14, 4, 5, 102, 3, (7, 8, 9), 6, (1, 2), 11, 10, (12, 13), 4, 3, 10, (12, 13), 5, 11, (7, 8, 9), 14, 6, 4, (7, 8, 9), 5, 10, (1, 2), 6, 3, 11, 4]
关于python - 从多个其他列表创建 n 项长播放列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44934917/