简体   繁体   English

Python,在随机索引处向向量添加值的最有效方法是什么?

[英]Python, what is the most efficient way to add values to a vector at a random indexes?

I am trying to find the best way to execute the following code.我正在尝试找到执行以下代码的最佳方法。 in practice i would be adding specific values at specific indices, not adding 1.在实践中,我会在特定索引处添加特定值,而不是添加 1。

#this is a simplified code for illustration purpose and must not be optimized

from random import randint, random
from numpy import zeros

n = 10
N = 1000

indicies = [randint(0, n-1) for p in range(0, N)]
values = [random.random() for p in range(0, N)]
x = zeros(n)
y = zeros(n)



#the issue is here. I want to do this as efficiently as possible :
for i in range(N):
    x[indicies[i]]+= values[i]

#I tried this but it does not work.
y[indicies]+= values


print(x)
print(y)

here is what i get by substituting the values vector by a vector of ones:这是我通过用一个向量替换值向量得到的:

#correct result
[103.  95. 109. 113.  79. 105.  90.  99. 105. 102.]
#failed attempt to go faster
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

I want to get x.我想得到x。 Obviously my attempt with y has failed.显然我对 y 的尝试失败了。

For those interested, i am computing conditional expectations in Monte Carlo, projecting values on a (time x space) grid.对于那些感兴趣的人,我在蒙特卡洛计算条件期望,在(时间 x 空间)网格上投影值。 So for 252 time steps of my stochastic process and 2^20 MC paths, i would be doing 250 * 2 million operations.因此,对于我的随机过程的 252 个时间步长和 2^20 个 MC 路径,我将进行 250 * 200 万次操作。 In practice the diffusion of the process is done by batches of 2^10 MC paths and efficiently vectorized but when i am projecting, i have not found a way to do it other than time step by time step and path by path.在实践中,该过程的扩散是通过 2^10 MC 路径的批次完成并有效地矢量化,但是当我进行投影时,除了逐个时间步长和逐个路径之外,我还没有找到其他方法。

This step of the algorithm take up 98% of the computation time so i must be doing something wrong.算法的这一步占用了 98% 的计算时间,所以我一定是做错了什么。

Thanks for your help.谢谢你的帮助。

Edit:编辑:

Given the first answers i must clarify my issue.鉴于第一个答案,我必须澄清我的问题。 I already have a vector of indexes, and a vector of values.我已经有一个索引向量和一个值向量。 The issue is not with generating random numbers.问题不在于生成随机数。 I am looking for an efficient way to increment my target vector:我正在寻找一种有效的方法来增加我的目标向量:

for i in range(N):
    target[indexes[i]]+=values[i]

Edit 2:编辑2:

The algorithm works, here is an illustration of what i get.该算法有效,这是我得到的说明。 it is just too slow:它太慢了:

look at it, it is quite cool看看它,它很酷

First, since you're using numpy , use np.random.randint for x :首先,由于您使用的是numpy ,因此将np.random.randint用于x

x = np.random.randint(0, n-1, N)

Then to add random values to x , just use another random vector and add it to x :然后要将随机值添加到x ,只需使用另一个随机向量并将其添加到x

x + np.random.randint(low, high, N)

RE: edit 2.回复:编辑 2。

Since you seem dead set on this approach, here's a possible solution, assuming I'm understanding you correctly:由于您似乎对这种方法一无所知,因此假设我正确理解您,这是一个可能的解决方案:

>>> indices = [0, 0, 4, 0, 1, 1, 2, 3, 4]
>>> values = [0, 0, 0, 0, 0]
>>> for idx in set(indices):
...     values[idx] += indices.count(idx)
...
>>> values
[3, 2, 1, 1, 2]

Use np.random.randint ( docs ).使用np.random.randint ( docs )。

How you might use it:你可以如何使用它:

n = 10
N = 1000
z = np.random.randint(0, N, size=n)

output: z = [292 237 838 860 590 933 29 154 168 606] output:z = [292 237 838 860 590 933 29 154 168 606]

accumulate 1000 random choices累积 1000 个随机选择

n = 10
N = 1000

indice = [random.randint(0, n-1) for p in range(0, N)]
values = [random.random() for p in range(0, N)]

x = zeros(n)
y = zeros(n)

def GetRandomChoice():
    index=random.choice(indice)
    value=values[index]
    return index,value

for i in range(N):
    index,value=GetRandomChoice()
    x[index]+= value
    index,value=GetRandomChoice()
    y[index]+= value

print(x,y)
output:
[  4.98649477  13.4498052  100.04144429  77.06294844  
   80.52940448 9.50733693  41.0324075   22.74005395  
   48.31112763  83.95712759]
[  5.24090776  14.72399728  81.06806692  92.87073274  
   75.9711363  8.36970687  37.00243891  18.15536565  
   58.40599011 116.76795906]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM