# Speed performance improvement needed. Using nested for loops

## Question:

I have a 2D array shaped (1002,1004). For this question it could be generated via:

```
a = numpy.arange( (1002 * 1004) ).reshape(1002, 1004)
```

What I do is generate two lists. The lists are generated via:

```
theta = (61/180.) * numpy.pi
x = numpy.arange(a.shape[0]) #(1002, )
y = numpy.arange(a.shape[1]) #(1004, )
max_y_for_angle = int(y[-1] - (x[-1] / numpy.tan(theta)))
```

The first list is given by:

```
x_list = numpy.linspace(0, x[-1], len(x))
```

Note that this list is identical to x. However, for illustration purposes and to give a clear picture I declared this ‘list’.

What I now want to do is create a y_list which is as long as x_list. I want to use these lists to determine the elements in my 2D array. After I determine and store the sum of the elements, I want to shift my y_list by one and determine the sum of the elements again. I want to do this for max_y_for_angle iterations. The code I have is:

```
sum_list = numpy.zeros(max_y_for_angle)
for idx in range(max_y_for_angle):
y_list = numpy.linspace((len(x) / numpy.tan(theta)) + idx, y[0] + idx , len(x))
elements = 0
for i in range(len(x)):
elements += a[x_list[i]][y_list[i]]
sum_list[idx] = elements
```

This operation works. However, as one might imagine this takes a lot of time due to the for loop within a for loop. The number of iterations of the for loops do not help as well. How can I speed things up? The operation now takes about 1 s. I’m looking for something below 200 ms.

Is it maybe possible to return a list of the 2D array elements when the inputs are x_list and y_list? I tried the following but this does not work:

```
a[x_list][y_list]
```

Thank you very much!

## Answers:

It’s possible to return an *array* of elements form a 2d array by doing `a[x, y]`

where `x`

and `y`

are both integer arrays. This is called advanced indexing or sometimes fancy indexing. In your question you mention lists a lot but never actually use any lists in your code, x_list and y_list are both arrays. Also, numpy multidimensional arrays are generally indexed `a[i, j]`

even when when `i`

and `j`

are integers values.

Using fancy indexing along with some clean up of you code produced this:

```
import numpy
def line_sums(a, thata):
xsize, ysize = a.shape
tan_theta = numpy.tan(theta)
max_y_for_angle = int(ysize - 1 - ((xsize - 1) / tan_theta))
x = numpy.arange(xsize)
y_base = numpy.linspace(xsize / tan_theta, 0, xsize)
y_base = y_base.astype(int)
sum_list = numpy.zeros(max_y_for_angle)
for idx in range(max_y_for_angle):
sum_list[idx] = a[x, y_base + idx].sum()
return sum_list
a = numpy.arange( (1002 * 1004) ).reshape(1002, 1004)
theta = (61/180.) * numpy.pi
sum_list = line_sums(a, theta)
```

Hope that helps.