Home > Enterprise >  Slicing with numpy in a for loop
Slicing with numpy in a for loop

Time:10-11

I have to work with x, x[:, :-1], x[:, :-2], etc. How to do this in a for loop?

for i in range(100):
    for j in range(100):
        y = x[:-i, :-j]

This works as desired if i and j are different than 0. But it fails if i or j is 0:

x[:, :-0]

is not x[:, :].

What is the standard Numpy way to do this?

Is there better than x[:x.shape[0]-i, :x.shape[1]-j]?

TL;DR:

  • y[:-1] is "all elements except the last one",
  • y[:-2] is "all elements except the two last ones",
  • but y[:-0] is NOT "all elements"

CodePudding user response:

One of possible solutions is to revert the order of iteration in both loops (start from the last index, in decreasing order).

Then you can refer to a range of elements starting from 0 (no number before the colon), ending at the index expressed by the loop control variable (after the colon).

If you want "original" values from your original loops, compute them as 10 - i and 10 - j.

To sum up, try the below code:

n = x.shape[0]
for i in range(n, 0, -1):
    for j in range(n, 0, -1):
        i2 = 10 - i
        j2 = 10 - j
        print(f'{i2}, {j2},  {i}, {j}\n{x[:i, :j]}')

Of course, for test purpose, use a smaller array, e.g. 10 * 10.

CodePudding user response:

One possible option is to use the array-length len inside:

y[:len(y)-2] #is all except the last two
y[:len(y)-1] #is all except the last one
y[:len(y)-0] #is all

CodePudding user response:

This is essentially the same as the prior answer but I would just create a reverted version of the array. It could be memory-inefficient, but slightly more readable.

x = np.arange(0, 25).reshape(5,5)
x_r = x[::-1, ::-1]
for i in range(5):
    for j in range(5):
        y = x_r[i:, j:]
  • Related