基本上我要做的是从列表中随机选择项目,同时保持内部分布。请参阅以下示例。
a = 17%
b = 12%
c = 4%
etc.
“a”在列表中有1700个项目。 “b”在列表中有1200个项目。 “c”在列表中有400个项目。
我想要一个模仿a,b,c等分布的样本,而不是使用所有信息。
所以目标是结束,
从“a”中随机选择170个项目 120个随机选择的项目来自“b” 从“c”中随机选择40个项目
我知道如何从列表中随机选择信息,但我无法弄清楚如何在强制结果具有相同分布时随机选择。
答案 0 :(得分:4)
如果您的列表不是很大且内存不是问题,您可以使用这种简单的方法。
要从n
,a
和b
获取c
个元素,您可以将这三个列表连接在一起,并使用{{3}从结果列表中选择随机元素}:
import random
n = 50
a = ['a'] * 170
b = ['b'] * 120
c = ['c'] * 40
big_list = a + b + c
random_elements = [random.choice(big_list) for i in range(n)]
# ['a', 'c', 'a', 'a', 'a', 'b', 'a', 'c', 'b', 'a', 'c', 'a',
# 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'a', 'a', 'a', 'c', 'a',
# 'c', 'a', 'b', 'a', 'a', 'c', 'a', 'b', 'a', 'c', 'b', 'a',
# 'a', 'b', 'a', 'b', 'a', 'a', 'c', 'a', 'c', 'a', 'b', 'c',
# 'b', 'b']
对于每个元素,从len(a) / len(a + b + c)
获取元素的概率为a
。
您可能会多次获得相同的元素。如果您不希望发生这种情况,可以使用random.choice
。
答案 1 :(得分:0)
根据我的理解,您有三个不同的群体,您想要随机抽取这些群体,但是选择某些群体的概率存在偏差。在这种情况下,首先生成对应于每个群体的索引列表更容易(因为我将它们组合成称为combined
的单个2D阵列)。
然后,您可以遍历随机生成的索引列表,这将为您提供您可以选择的人口,然后使用np.random.choice()
从该数据中随机选择。
import numpy as np
sample_a = np.arange(1, 1000)
sample_b = np.arange(1001, 2000)
sample_c = np.arange(2001, 3000)
combined = np.vstack((sample_a, sample_b, sample_c))
distributions = [0.7, 0.2, 0.1] # The skewed probability distribution for sampling
sample = np.random.choice([0, 1, 2], size=10, p=distributions) # Choose indices with skewed probability
combined_pool = []
for arr in sample:
combined_pool.append(np.random.choice(combined[arr]))
答案 2 :(得分:0)
在您的选择中“模仿”此类分布的一种方法是简单地将列表合并为一个,然后从该列表中选择所需的总项目数。如果需要选择的项目总数很大,那么这个近似值就会很好。
请注意,它并不能保证将精确选择每个列表中的数量。但是,如果列表很大并且此例程有很多次运行,则平均值应该很好。
import random
total = a + b + c + ...
samples = []
number = len(total) / 10
for i in range(number):
samples.append(total[random.rand(0, len(total) - 1])
答案 3 :(得分:0)
手动执行此操作非常简单。让我们将您的数据存储在(value, probability)
个对象列表中:
data = [(a, 0.17), (b, 0.12), (c, 0.04), ...]
这个函数可以帮助您选择遵循概率分布的随机值:
import random
def select_random_element(data):
sample_proba = random.uniform(0, 1)
total_proba = 0
for (value, proba) in data:
total_proba += proba
if total_proba >= sample_proba:
return value
最后,这是我们选择N个随机项目的方式:
random_items = [select_random_element(data) for _ in range(0, N)]
这不需要任何额外的内存。但是,时间复杂度为O(len(data)*N)
。这可以通过事先降低概率对数据列表进行排序来改进:
data = sorted(data, key=lambda i: i[1], reverse=True)
请注意,我假设您的数据的总概率为1.如果不是,您应该在上面的代码中写random.uniform(0, total_probability)
而不是random.uniform(0, 1)
,其中包含:
total_probability = sum([i[1] for i in data])
答案 4 :(得分:-1)
只需在列表中使用shuffle
,然后取前n个元素。