Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract a block from an 2d array

Suppose you have a 2D array filled with integers in a continuous manner, going from left to right and top to bottom. Hence it would look like

[[ 0,  1,  2,  3,  4],
 [ 5,  6,  7,  8,  9],
 [10, 11, 12, 13, 14],
 [15, 16, 17, 18, 19]]

Suppose now you have a 1D array of some of the integers shown in the array above. Lets say this array is [6,7,11]. I want to extract the block/chunk of the 2D array that contains the elements of the list. With these two inputs the result should be

[[ 6.,  7.],
 [11., nan]]

(I am padding with np.nan is it cannot be reshaped)

This is what I have written. Is there a simpler way please?

import numpy as np
def my_fun(my_list):
    ids_down = 4
    ids_across = 5
    layout = np.arange(ids_down * ids_across).reshape((ids_down, ids_across))

    ids = np.where((layout >= min(my_list)) & (layout <= max(my_list)), layout, np.nan)
    r,c = np.unravel_index(my_list, ids.shape)
    out = np.nan*np.ones(ids.shape)
    for i, t in enumerate(zip(r,c)):
        out[t] = my_list[i]

    ax1_mask = np.any(~np.isnan(out), axis=1)
    ax0_mask = np.any(~np.isnan(out), axis=0)
    out = out[ax1_mask, :]
    out = out[:, ax0_mask]

    return out

Then trying my_fun([6,7,11]) returns

[[ 6.,  7.],
 [11., nan]]
like image 487
Aenaon Avatar asked Feb 23 '26 01:02

Aenaon


1 Answers

This 100% NumPy solution works for both contiguous and non-contiguous arrays of wanted numbers.

a = np.array([[ 0,  1,  2,  3,  4],
              [ 5,  6,  7,  8,  9],
              [10, 11, 12, 13, 14],
              [15, 16, 17, 18, 19]])
n = np.array([6, 7, 11])

Identify the locations of the wanted numbers:

mask = np.isin(a, n)

Select the rows and columns that have the wanted numbers:

np.where(mask, a, np.nan)\
       [mask.any(axis=1)][:, mask.any(axis=0)]
#array([[ 6.,  7.],
#       [11., nan]])
like image 59
DYZ Avatar answered Feb 24 '26 15:02

DYZ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!