Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy how to slice index an array using arrays?

Tags:

python

numpy

Perhaps this has been raised and addressed somewhere else but I haven't found it. Suppose we have a numpy array:

a = np.arange(100).reshape(10,10)
b = np.zeros(a.shape)
start = np.array([1,4,7])   # can be arbitrary but valid values
end = np.array([3,6,9])     # can be arbitrary but valid values

start and end both have valid values so that each slicing is also valid for a. I wanted to copy value of subarrays in a to corresponding spots in in b:

b[:, start:end] = a[:, start:end]   #error

this syntax doesn't work, but it's equivalent to:

b[:, start[0]:end[0]] = a[:, start[0]:end[0]]
b[:, start[1]:end[1]] = a[:, start[1]:end[1]]
b[:, start[2]:end[2]] = a[:, start[2]:end[2]]

I wonder if there is a better way of doing this instead of an explicit for-loop over the start and end arrays.

Thanks!

like image 628
galactica Avatar asked Oct 13 '17 16:10

galactica


People also ask

How do I cut a Numpy array of arrays?

Slice Two-dimensional Numpy Arrays To slice elements from two-dimensional arrays, you need to specify both a row index and a column index as [row_index, column_index] . For example, you can use the index [1,2] to query the element at the second row, third column in precip_2002_2013 .

Can you slice Numpy arrays?

One-Dimensional SlicingThe first item of the array can be sliced by specifying a slice that starts at index 0 and ends at index 1 (one item before the 'to' index). Running the example returns a subarray with the first element. We can also use negative indexes in slices.

How do I select a specific index in a Numpy array?

To select an element from Numpy Array , we can use [] operator i.e. It will return the element at given index only.

How can we create Numpy array explain indexing and slicing?

Numpy with PythonContents of ndarray object can be accessed and modified by indexing or slicing, just like Python's in-built container objects. As mentioned earlier, items in ndarray object follows zero-based index. Three types of indexing methods are available − field access, basic slicing and advanced indexing.


1 Answers

We can use broadcasting to create a mask of places to be edited with two sets of comparisons against start and end arrays and then simply assign with boolean-indexing for a vectorized solution -

# Range array for the length of columns
r = np.arange(b.shape[1])

# Broadcasting magic to give us the mask of places
mask = (start[:,None] <= r) & (end[:,None] >= r)

# Boolean-index to select and assign 
b[:len(mask)][mask] = a[:len(mask)][mask]

Sample run -

In [222]: a = np.arange(50).reshape(5,10)
     ...: b = np.zeros(a.shape,dtype=int)
     ...: start = np.array([1,4,7])
     ...: end = np.array([5,6,9]) # different from sample for variety
     ...: 

# Mask of places to be edited
In [223]: mask = (start[:,None] <= r) & (end[:,None] >= r)

In [225]: print mask
[[False  True  True  True  True  True False False False False]
 [False False False False  True  True  True False False False]
 [False False False False False False False  True  True  True]]

In [226]: b[:len(mask)][mask] = a[:len(mask)][mask]

In [227]: a
Out[227]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])

In [228]: b
Out[228]: 
array([[ 0,  1,  2,  3,  4,  5,  0,  0,  0,  0],
       [ 0,  0,  0,  0, 14, 15, 16,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0, 27, 28, 29],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0]])
like image 92
Divakar Avatar answered Oct 18 '22 06:10

Divakar