Average 3d numpy array with more weight for central slices - python

I have a set of 3D numpy arrays of size 128x128x64.
I want to reduce these into 128x128 by averaging over the third axis, and am currently doing that using this line
np.mean(X, axis=2)
However, the pattern of the data is that the outer slices, contain less influential information and the central slices contain more.
Is there anyway I can average over the slices giving preference/more weight to the central slices and slowly decreasing out to the outer ones?
Either that or the important data in the arrays is usually bunched up and has the highest intensity. If there is anyway I can give preference to these regions whilst averaging please suggest any ideas.
Thanks

Related

Is it possible to calculate running statistics having neighbours into account in Numpy?

I have a rank-3 matrix A of shape (Nx, Ny, Nt), and I need calculate statistics in the third (temporal) dimension for all grid points (the first two dimensions correspond to horizontal space). For this, you can just make something like np.percentile(A, 0.5, axis=2). So far so good.
Now, my actual problem is more convoluted. I'd like to have neighbours into account to make some sort of calculation over a "running window" of a given size, or even an arbitrary shape. This sounds like a convolution, but I want to calculate something else than just the average. I need percentiles and things like such.
How can I achieve this result efficiently without explicit looping in the spatial dimensions?
I was thinking that a plausible solution would be to "enlarge" the original matrix by including an additional dimension that copies the data from the neighbours in the additional dimension. Something like B of shape (Nx, Ny, Nt, Nn), where Nn is the number of neighbours (let's assume we take the 8 closest neighbours for the sake of simplicity). Then, I could calculate np.percentile(B.reshape(Nx, Ny, Nt*Nn), 0.5, axis=2). The problem with this approach is two-fold:
I don't know how to build this matrix without explicit looping.
I'm concerned with the memory cost of having a Nn redundant copies of the original array. In the actual application, the matrix will be very large and the number of neighbours will also larger than 8.
Overall, I do not think this procedure is any better than explicitly looping and calculating things on each grid point in each iteration.
I'm pretty sure there must be more convenient and standardised way to have neighbours into account within the Numpy matricial approach, but I could not find the recipe online.

Computing maximum and minimum diameter of a 3D tubular shape

My aim is to compute the maximum and minimum diameters of a slice of a 3D tubular shape (as shown in the attached figure).
What I tried : several rotations of the skeleton of the shape to make it parallel to the Z axis and then cut the interpolated tubular shape at some voxel to get the slice.
However these rotations make lot of interpolations. Hence, I would like to avoid these with a method that computes the diameters (max and min) without using rotations.
Any help please?

Efficiently filter 3D matrix in numpy with variable 2D masks

I have a 3D numpy array points of dimensions [10000x3000x128] where the first dimension is the number of frames, the second dimension the number of points in each frame and the third dimension is a 128-element feature vector associated to each point. What I want to do is to efficiently filter the points in each frame by using a boolean 2D mask of dimensions [10000x3000] and for each of the selected points also take the related 128-dim vector of features. Moreover, in output I need still a 3D vector and not a merged 2D vector and possibly avoid any for loop.
Actually what I'm doing is:
# example of points
points = np.array([10000, 3000, 128])
# fg, bg = 2D dimensional boolean np.array
# init empty lists
fg_points, bg_points = [], []
for i in range(points.shape[0]):
fg_mask_tmp, bg_mask_tmp = fg[i], bg[i]
fg_points.append(points[i,fg_mask_tmp,:])
bg_points.append(points[i,bg_mask_tmp,:])
fg_features, bg_features = np.array(fg_points), np.array(bg_points)
But this is a quite naive solution that for sure can be improved in a more numpy-like way.
In addition, I also tried other solutions as:
fg_features = points[fg,:]
But this solution does not preserve the dimensions of the array merging the two first dimensions since the number of filtered points for each frame can vary.
Another solution I tried is to enlarge the 2D masks by appending a [128] true value to the last dimension, but with any successful result.
Dos anyone know a possible efficient solution?
Thank you in advance for any help!

1D plots from 3D array

I have a 3D data cube and I am trying to make a plot of the first axis at a specific value of the other two axes. The goal is to make a velocity plot at given coordinates in the sky.
I have tried to create an 1D array from the 3D array by putting in my values for the last two axes. This is what I have tried
achan=50
dchan = 200
lmcdata[:][achan][dchan] #this array has three axes, vchan, achan, dchan.
I am expecting an array of size 120 as there are 120 velocity channels that make up the vchan axis. When trying the code above I keep getting an array of size 655 which is the number of entries for the dchan axis.
Python slicing works from left to right. In this case, lmcdata[:] is returning the whole lmcdata list. So, lmcdata[:][achan][dchan] is equivalent to just lmcdata[achan][dchan].
For higher level indexing and slicing tasks like this, I highly recommend the numpy package. You will be able to slice lmcdata as expected after turning it into a numpy array: lmcdata = np.asarray(lmcdata).

How do HEALPix FITS files of CMB maps translate into ndarrays? What are the coordinates?

I'm using Healpy (the HEALPix tools developed in Python) to read and write full-sky CMB maps.
I am confused as to how the coordinates of pixels on a sky map translates into entries of a numpy ndarray. How does one HEALPix pixel in a FITS file translate into an ndarray entry?
For example, let's say I have a generated CMB map, Nside=64, lmax=64, using the default RING scheme. The total number of pixels is given by Npix=12*Nside**2. So, for my example, that is 49152 total number of pixels.
The FITS file I have is in the format 1 column by 48 rows. (The 1 column is all temperature values.) So, I transform this file into a n-dim numpy ndarray. The shape of this array gives (48,1024).
Question 1: Is this 2-d array a projection of all the map pixels on the sky into "matrix" form? I think it is. Using my example, 48*1024 = 49152, the total number of pixels.
Question 2: Where does the 1024 standard come from? What does this mean in terms of a HEALPix map and its coordinates? How does one 2-dim ndarray entry (pixel) relate to another (by angle, by HEALPix position, etc.)?
For another example, map Nside=1024. When I convert this into a 2-dimensional ndarray, I get the shape (12288, 1024).
EDIT: Why does this convention of 1024-element arrays exist? How does this correspond to the pixel coordinates on a map?
the best source of information about the HEALPIX pixelization is the Healpix primer:
http://healpix.jpl.nasa.gov/html/intro.htm
A map is a 1-dimensional vector, each index is a pixel in the sky.
you can turn pixel number into coordinates in the sky using hp.pix2ang.
Shaping it in rows of 1024 is just a trick to make read/write to disk faster.

Categories