Given a 3D numpy matrix D , I need to extract a 3D slice given a boolean vector b and index vector k.
- D is a 3D Numpy array with dimensions (P, n, n) and data type float.
- b is a 1D Numpy array with dimensions (P,) and data type bool.
- k is a 1D Numpy array with dimensions (P,) and data type int.
b is populated based on a prior comparison check on D.
Each element p of k corresponds to the desired start index (for the slicing operation) for the pth 2D matrix in D, where:
0≤p<P and 0≤k[p]<n-1
It is important to keep in mind that the elements of k are not uniform.
I can do element wise assignment and extraction i.e,
F[b,k[b],k[b]] = D[b,k[b],k[b]]
where F had the same dimensions as D.
But I cannot generate a 3D matrix G, which should be created by extracting Rx2x2 slices from D. R≤P and is the number of elements in b that satisfy the boolean condition.
Ignoring b, I wish to do something like the following:
G = D[:,k:(k+1), k:(k+1)]
where the pth 2D slice of D can be visualized below:
+------------------+----------------------+
| (k[p], k[p]) | (k[p], k[p] + 1) |
+------------------+----------------------+
| (k[p] + 1, k[p]) | (k[p] + 1, k[p] + 1) |
+------------------+----------------------+
Executing the line of code preceding the tabular representation understandably returns a Type Error.
TypeError: only integer scalar arrays can be converted to a scalar index
How do I generate G, without using a for loop to iterate through the first axis (axis 0)? Is a vectorized solution possible?
A small python script is attached below as a minimal example and in order to recreate the problem i am facing.
import numpy as np
P = 4096
n = 4
D = np.random.default_rng().normal(scale=1, size=(P,n,n))
k = np.zeros((P,), dtype=int)
# Is the top-left element in each pth n*n slice of D <= 0.5 ?
b = np.less_equal(D[:,0,0], 0.5)
# Create a 3D array with dimensions similar to D
F = np.zeros((P,n,n),)
# Replace for top left element at axis 0 indices (p) for which b is True
F[b,k[b],k[b]] = D[b,k[b],k[b]]
# Attempt to generate G. Type Error: only integer scalar arrays can be converted to a scalar index
G = D[b,k[b]:k[b]+1, k[b]:k[b]+1]
# Init G as a P*2*2 array.
G =np.zeros((P,2,2),)
#Attempt to populate G with 2x2 slices from D if b[p] is True and given base indices in k for pth slice.
# TypeError: only integer scalar arrays can be converted to a scalar index
G[b,k[b]:k[b]+1, k[b]:k[b]+1] = D[b,k[b]:k[b]+1, k[b]:k[b]+1]