Basj
Basj

Reputation: 46473

Slicing with numpy in a for loop

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:

Upvotes: 0

Views: 60

Answers (3)

atommy
atommy

Reputation: 58

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:]

Upvotes: 0

Valdi_Bo
Valdi_Bo

Reputation: 30971

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.

Upvotes: 1

flyakite
flyakite

Reputation: 799

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

Upvotes: 1

Related Questions