Python Forum

Full Version: Slicing using vectors
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all

Does somebedoy know how to use vectors for slicing (see code herebellow)?

I got the following error "only integer scalar arrays can be converted to a scalar index" but I do not understand since I'm using a scalar (numpy) array, or I'm missing something

Thanks

Paul

n = 100
m = 2
A = np.random.randint(66, size=(n,m), dtype=np.int32)
i = np.random.randint(n-4, size=int(0.5*n), dtype=np.int32)
j = i + 4*np.ones(int(0.5*n), dtype=np.int32)
extract1_A = A[i,:]     # as usual = OK
#extract2_A = A[i:i+4,:] # fails
extract3_A = A[i:j,:] # fails
Try this:

import numpy as np
n = 100
m = 2
A = np.array(np.random.randint(66, size=(n,m), dtype=np.int32))
i = np.array(np.random.randint(n-4, size=int(0.5*n), dtype=np.int32))
j = i + 4*np.ones(int(0.5*n), dtype=np.int32)
print(i)
print(j)
print(i.shape)
print(j.shape)
extract1_A = np.array(A[i,:])
extract2_A = np.array([ A[x:x+4,:] for x in i])
extract3_A = np.array([ A[x:y,:] for x in i for y in j])
print (extract1_A.shape)
print (extract2_A.shape)
print (extract3_A.shape)
Smile wish everyone happy coding Smile
thanks for the interest, but the goal has ever been to avoid the use of loops.

Be carefull with the dimensions of your matrixes

Paul
It's generally helpful if you post runnable code (yours lacks at least one import) and the full, verbatim error message (ideally in error tags). Here's what I get when I run your code after adding the import:
Error:
Traceback (most recent call last): File "doit.py", line 10, in <module> extract3_A = A[i:j,:] # fails TypeError: only integer scalar arrays can be converted to a scalar index
(Nov-14-2019, 10:06 AM)paul18fr Wrote: [ -> ]I got the following error "only integer scalar arrays can be converted to a scalar index" but I do not understand since I'm using a scalar (numpy) array, or I'm missing something
So I tried printing your object and I got something like this:
Output:
[[22 45] [24 48] [51 24] [23 63] [ 9 29] .../
That... looks like a collection of non-scalars to me. I don't usually link to SO, but this might be useful.
(Nov-16-2019, 12:00 AM)micseydel Wrote: [ -> ]It's generally helpful if you post runnable code (yours lacks at least one import) and the full, verbatim error message (ideally in error tags). Here's what I get when I run your code after adding the import:
Error:
Traceback (most recent call last): File "doit.py", line 10, in <module> extract3_A = A[i:j,:] # fails TypeError: only integer scalar arrays can be converted to a scalar index

The code has been added as it stands to highlight the issue I got.

Finally I found a way that answers to my need without using any loop but the Kronecker product; it has been checked on a small size matrix, but it quite interesting with million of lines (tested with 10 million on my old laptop).

Paul
import time
import numpy as np

#n = 1_000_000
n = 10
m = 2
A = np.array(np.random.randint(66, size=(n,m), dtype=np.int32))
i = np.array(np.random.randint(n-4, size=int(0.5*n), dtype=np.int32))
j = i + 4*np.ones(int(0.5*n), dtype=np.int32)

## the i vector gives us the first index of values we want to get from A
## in the current case we want to get values from i to (i+4)
## with only 1 index, slicing is traditionnally used as A[100:104,4] for example

## the "trick" or the solution I've been using is to specify each index I want to extract
## using the Kronecker product as follow:
t0 = time.time()
k1 = np.arange(4, dtype=np.int32)
k2 = np.ones(int(0.5*n), dtype=np.int32)
k3 = np.ones(4, dtype=np.int32)
kron1 = np.kron(k2,k1)  # here [0 1 2 3] is repeated (0.5*n) times => from j vector
kron2 = np.kron(i,k3)   # here each index is repeated (0.5*n) times => from i vector
index = kron1 + kron2   # then each index varies from its initial value to (initial+4)
Extract_A = np.copy(A[index,:]) # all the indexes have been explicitly expressed and we can extract the values as usually
t1 = time.time()
print("The new solution took {} seconds".format(t1-t0))