david
david

Reputation: 580

Efficient way to fill Numpy Array

I'm looking for a more efficient way to fill a 2d numpy array than a double for-loop. The issue I am having is that the array values are dependent on several other arrays.

In the following code k and d are integers, and y and result are arrays. Any help would be greatly appreciated.

for i in xrange(1,d):
    for j in xrange(k-i-1, k+1):
        result[j][i] = ((x - y[j])/(y[j+i] - y[j]))*result[j,i-1] + ((y[j+i+1]-x)/(y[j+i+1] - y[j+1]))*result[j+1,i-1]

Upvotes: 1

Views: 1036

Answers (2)

tacaswell
tacaswell

Reputation: 87566

You can get rid of the inner loop via clever broadcasting

tmp = ((x - y[k-i+1:k+1])/(y[k+1:k+1+i] - y[j]))*result[k-i+1:k+1,i-1] + ((y[k+2:k+i+2]-x)/(y[k+2:k+i+2] - y[k-i+2:k+2]))*result[k-i+2:k+2,i-1]
result[k-i+1:k+1, i] = tmp

but because you bounds in the inner loop depend on the outer-loop you can not remove it through broadcasting as well.

I used tmp in an overabundance of caution

Upvotes: 4

Jaime
Jaime

Reputation: 67507

You seem to be updating your result array one column at a time, using data from the previously updated column. That makes it hard to vectorize the outer loop, I don't think you can do it unless there is some structure to your data that can be exploited. The inner loop is very straightforward to vectorize:

for i in xrange(1, d):
    j = np.arange(k-i-1, k+1)
    result[j, i] = ((x - y[j]) / (y[j+i] - y[j]) * result[j, i-1] +
                    (y[j+i+1] - x) / (y[j+i+1] - y[j+1]) * result[j+1, i-1])

There is some marginal improvement you could get by defining a base_j = np.arange(k-d-2, k+1) array outside the loop, and then slicing it inside the loop with something like j = base_j[d-i+1:].

Upvotes: 4

Related Questions