使用python查找比例采样
我遇到一个明确要求我不要使用numpy和pandas的问题 概率:从列表中随机选择一个元素,概率与其大小成正比。假设我们正在进行100次相同的替换实验,在每次实验中,您将打印一个从a中随机选择的数字使用python查找比例采样,python,python-3.x,Python,Python 3.x,我遇到一个明确要求我不要使用numpy和pandas的问题 概率:从列表中随机选择一个元素,概率与其大小成正比。假设我们正在进行100次相同的替换实验,在每次实验中,您将打印一个从a中随机选择的数字 Ex 1: A = [0 5 27 6 13 28 100 45 10 79] let f(x) denote the number of times x getting selected in 100 experiments. f(100) > f(79) > f(45) > f
Ex 1: A = [0 5 27 6 13 28 100 45 10 79]
let f(x) denote the number of times x getting selected in 100 experiments.
f(100) > f(79) > f(45) > f(28) > f(27) > f(13) > f(10) > f(6) > f(5) > f(0)
最初,我计算了列表A中所有元素的总和
然后,我将列表A中的每个元素除以和(为了规范化),并将这些值存储在另一个列表中(d_破折号)
然后我创建了另一个空列表(d_栏),它接受d_栏所有元素的累加和
创建变量r,其中r=random.uniform(0.0,1.0),然后对于d_破折号的长度,将r与d_破折号[k]进行比较,如果r可以通过
itertools.accumulate
计算累积和。循环:
for p in range(len(d_bar)):
if(r<=d_bar[p]):
number=d_bar[p]
打印(例如):
您收到“列表索引超出范围”消息的原因是您创建了一个空列表“d_bar=[]”,并开始为其赋值“d_bar[k]=d_bar[k]+d_dash[k]”。我使用以下结构器isntead重新声明:
首先,用这种方式定义它:
d_bar=[0表示范围内的i(len(A))]
此外,我相信这段代码将永远返回1,因为循环中没有中断。您可以通过添加“中断”来解决此问题。以下是您的代码的更新版本:
A = [0, 5, 27, 6, 13, 28, 100, 45, 10, 79]
def pick_a_number_from_list(A):
sum=0
for i in A:
sum+=i
A_norm=[]
for j in A:
A_norm.append(j/sum)
A_cum=[0 for i in range(len(A))]
A_cum[0]=A_norm[0]
for k in range(len(A_norm)-1):
A_cum[k+1]=A_cum[k]+A_norm[k+1]
A_cum
r = random.uniform(0.0,1.0)
number=0
for p in range(len(A_cum)):
if(r<=A_cum[p]):
number=A[p]
break
return number
def sampling_based_on_magnitued():
for i in range(1,100):
number = pick_a_number_from_list(A)
print(number)
sampling_based_on_magnitued()
A=[0,5,27,6,13,28100,45,10,79]
def从列表(a)中选择一个编号:
总和=0
对于我来说,在一个:
总和+=i
A_范数=[]
对于A中的j:
A_范数追加(j/和)
A_cum=[0表示范围内的i(len(A))]
A_cum[0]=A_范数[0]
对于范围内的k(len(A_norm)-1):
A_cum[k+1]=A_cum[k]+A_范数[k+1]
A_cum
r=随机均匀(0.0,1.0)
数字=0
对于范围内的p(len(A_cum)):
如果(r下面是执行相同操作的代码:
A = [0, 5, 27, 6, 13, 28, 100, 45, 10, 79]
#Sum of all the elements in the array
S = sum(A)
#Calculating normalized sum
norm_sum = [ele/S for ele in A]
#Calculating cumulative normalized sum
cum_norm_sum = []
cum_norm_sum.append(norm_sum[0])
for itr in range(1, len(norm_sum), 1) :
cum_norm_sum.append(cum_norm_sum[-1] + norm_sum[itr])
def prop_sampling(cum_norm_sum) :
"""
This function returns an element
with proportional sampling.
"""
r = random.random()
for itr in range(len(cum_norm_sum)) :
if r < cum_norm_sum[itr] :
return A[itr]
#Sampling 1000 elements from the given list with proportional sampling
sampled_elements = []
for itr in range(1000) :
sampled_elements.append(prop_sampling(cum_norm_sum))
A=[0,5,27,6,13,28100,45,10,79]
#数组中所有元素的总和
S=总和(A)
#计算归一化和
norm_sum=[A中元素的元素/S]
#计算累积归一化和
总和标准总和=[]
cum\u norm\u sum.append(norm\u sum[0])
对于范围内的itr(1,len(norm_sum),1):
追加(cum_norm_sum[-1]+norm_sum[itr])
def属性采样(总和):
"""
此函数返回一个元素
采用比例抽样。
"""
r=random.random()
对于范围内的itr(len(cum_norm_sum)):
如果r
下图显示了采样点中每个元素的频率:
A = [0, 5, 27, 6, 13, 28, 100, 45, 10, 79]
#Sum of all the elements in the array
S = sum(A)
#Calculating normalized sum
norm_sum = [ele/S for ele in A]
#Calculating cumulative normalized sum
cum_norm_sum = []
cum_norm_sum.append(norm_sum[0])
for itr in range(1, len(norm_sum), 1) :
cum_norm_sum.append(cum_norm_sum[-1] + norm_sum[itr])
def prop_sampling(cum_norm_sum) :
"""
This function returns an element
with proportional sampling.
"""
r = random.random()
for itr in range(len(cum_norm_sum)) :
if r < cum_norm_sum[itr] :
return A[itr]
#Sampling 1000 elements from the given list with proportional sampling
sampled_elements = []
for itr in range(1000) :
sampled_elements.append(prop_sampling(cum_norm_sum))
很明显,每个元素出现的次数与其大小成正比。d\u dash
为空,因此它没有元素:d\u dash[j].append
将始终引发异常。您只需使用d_破折号。append
。无需指定要在末尾追加的索引。与d_bar=[]相同;d_bar[0]=0
d_bar
没有元素,因此d_bar[0]
无效。您可以只编写d_bar=[0]
并使用append
通常感谢您的回复。我使用d_条存储累加和。如果对范围内的k(len(A))使用以下d_条=[0]:d_条。append(d_条+d_破折号[k])我得到的错误只能连接列表(而不是“float”)感谢你的回复Andrej,这真的很有帮助。我有几个问题:1)我可以知道为什么我们要做icum_sum[-1],也就是用I(0,1)乘以cum_sum中的最后一个元素吗?idx=bisect(cum_sum,icum_sum[-1])它不应该是idx=bisect(cum_sum,i)?2) 感谢您分享itertools.acculate来计算cum_sum,我想知道是否有一种方法可以在不导入此项的情况下完成此操作?i、 香草蟒蛇。提前感谢。@hemanthavavarapucum\u sum[-1]
是cum\u sum
列表中的最大值<代码>i在间隔0、1中。通过将这两个值相乘,我们得到了区间中的值,我感到困惑,因为在我上面共享的代码中,我将列表A的每个元素除以A的所有元素之和,并将它们存储在列表d_中。现在,如果我使用cum_sum=[*accumlate(d_dash)]而不是cum_sum=[*accumulate(A)],然后使用idx=bisect(cum_sum,I),我将在(0,1)中生成I,然后将其与cum_sum中的每个元素(在我的情况下,它们是小数)进行比较,然后给出A的索引。我的这种方法会产生相同的结果吗(与我们处理概率的方法不完全相同,但在逻辑上)结果与您的结果相同吗?@Hemantravavarapu从您给出的描述中,我看不出错误-方法相同,但您只是将值作为额外步骤进行分割。当然,测试:)
A = [0, 5, 27, 6, 13, 28, 100, 45, 10, 79]
def pick_a_number_from_list(A):
sum=0
for i in A:
sum+=i
A_norm=[]
for j in A:
A_norm.append(j/sum)
A_cum=[0 for i in range(len(A))]
A_cum[0]=A_norm[0]
for k in range(len(A_norm)-1):
A_cum[k+1]=A_cum[k]+A_norm[k+1]
A_cum
r = random.uniform(0.0,1.0)
number=0
for p in range(len(A_cum)):
if(r<=A_cum[p]):
number=A[p]
break
return number
def sampling_based_on_magnitued():
for i in range(1,100):
number = pick_a_number_from_list(A)
print(number)
sampling_based_on_magnitued()
A = [0, 5, 27, 6, 13, 28, 100, 45, 10, 79]
#Sum of all the elements in the array
S = sum(A)
#Calculating normalized sum
norm_sum = [ele/S for ele in A]
#Calculating cumulative normalized sum
cum_norm_sum = []
cum_norm_sum.append(norm_sum[0])
for itr in range(1, len(norm_sum), 1) :
cum_norm_sum.append(cum_norm_sum[-1] + norm_sum[itr])
def prop_sampling(cum_norm_sum) :
"""
This function returns an element
with proportional sampling.
"""
r = random.random()
for itr in range(len(cum_norm_sum)) :
if r < cum_norm_sum[itr] :
return A[itr]
#Sampling 1000 elements from the given list with proportional sampling
sampled_elements = []
for itr in range(1000) :
sampled_elements.append(prop_sampling(cum_norm_sum))