move values of 3d array knowing new coordinates with mask

  • Last Update :
  • Techknowledgy :

Your map matrices are wrong, to get the result you want they need to be like these (since, when you put values into b, you are checking if m[k, j, i] != -1 and you want the last columns to be 0, not the first ones)

mx = np.array([
   [
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.]
   ],

   [
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.],
      [1., 2., 3., 4., -1.]
   ]
])

my = np.array([
   [
      [2., 2., 2., 2., -1.],
      [3., 3., 3., 3., -1.],
      [4., 4., 4., 4., -1.],
      [-1., -1., -1., -1., -1.],
      [-1., -1., -1., -1., -1.]
   ],

   [
      [2., 2., 2., 2., -1.],
      [3., 3., 3., 3., -1.],
      [4., 4., 4., 4., -1.],
      [-1., -1., -1., -1., -1.],
      [-1., -1., -1., -1., -1.]
   ]
])

Also in your loops, it would be better to switch the dimensions in the first and second loops so they become

for i in range(IRtest.shape[2]):
   for j in range(IRtest.shape[1]):
   for k in range(IRtest.shape[0]):

To summarize the answer to your previous question regarding 2dim, you can simply use fancy-indexing like (after fixing the dtypes of your arrays, of course):

b = IRtest[my, mx] * ~(mask_my | mask_mx)

Now, in order to apply the same technique to the 3dim case, you need to create a "neutral" index array, to apply to the first axis. This is where np.indices comes useful:

mz = np.indices(IRtest.shape)[0] # take[0] because we need to be neutral w.r.t.axis = 0

Now apply the fancy indexing:

b = IRtest[mz, my, mx]

As in the 2dim case, you could alrenatively use fancy-assignment (again, axis=0 is being broadcast):

b[unified_mask[np.newaxis, ...]] = 0.

Suggestion : 2

Fancy indexing is conceptually simple: it means passing an array of indices to access multiple array elements at once. For example, consider the following array:,Fancy indexing also works in multiple dimensions. Consider the following array:,All of these indexing options combined lead to a very flexible set of operations for accessing and modifying array values.,Just as fancy indexing can be used to access parts of an array, it can also be used to modify parts of an array. For example, imagine we have an array of indices and we'd like to set the corresponding items in an array to some value:

import numpy as np
rand = np.random.RandomState(42)

x = rand.randint(100, size = 10)
print(x)
[51 92 14 71 60 20 82 86 74 74]
[x[3], x[7], x[2]]
[71, 86, 14]
ind = [3, 7, 4]
x[ind]
array([71, 86, 60])

Suggestion : 3

ndarray, a fast and space-efficient multidimensional array providing vectorized arithmetic operations and sophisticated broadcasting capabilities,NumPy array indexing is a rich topic, as there are many ways you may want to select a subset of your data or individual elements. One-dimensional arrays are simple; on the surface they act similarly to Python lists:,The easiest way to create an array is to use the array function. This accepts any sequence-like object (including other arrays) and produces a new NumPy array containing the passed data. For example, a list is a good candidate for conversion:,The last bullet point is also one of the most important ones from an ecosystem point of view. Because NumPy provides an easy-to-use C API, it is very easy to pass data to external libraries written in a low-level language and also for external libraries to return data to Python as NumPy arrays. This feature has made Python a language of choice for wrapping legacy C/C++/Fortran codebases and giving them a dynamic and easy-to-use interface.

In[13]: data1 = [6, 7.5, 8, 0, 1]

In[14]: arr1 = np.array(data1)

In[15]: arr1
Out[15]: array([6., 7.5, 8., 0., 1.])
In[27]: arr1 = np.array([1, 2, 3], dtype = np.float64)

In[28]: arr2 = np.array([1, 2, 3], dtype = np.int32)

In[29]: arr1.dtype In[30]: arr2.dtype
Out[29]: dtype('float64') Out[30]: dtype('int32')
In[45]: arr = np.array([
   [1., 2., 3.],
   [4., 5., 6.]
])

In[46]: arr
Out[46]:
   array([
      [1., 2., 3.],
      [4., 5., 6.]
   ])

In[47]: arr * arr In[48]: arr - arr
Out[47]: Out[48]:
   array([
      [1., 4., 9.], array([
         [0., 0., 0.],
         [16., 25., 36.]
      ])[0., 0., 0.]
   ])
In[51]: arr = np.arange(10)

In[52]: arr
Out[52]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In[53]: arr[5]
Out[53]: 5

In[54]: arr[5: 8]
Out[54]: array([5, 6, 7])

In[55]: arr[5: 8] = 12

In[56]: arr
Out[56]: array([0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In[75]: arr[1: 6]
Out[75]: array([1, 2, 3, 4, 64])
In[83]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])

In[84]: data = np.random.randn(7, 4)

In[85]: names
Out[85]:
   array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],
      dtype = '|S4')

In[86]: data
Out[86]:
   array([
      [-0.048, 0.5433, -0.2349, 1.2792],
      [-0.268, 0.5465, 0.0939, -2.0445],
      [-0.047, -2.026, 0.7719, 0.3103],
      [2.1452, 0.8799, -0.0523, 0.0672],
      [-1.0023, -0.1698, 1.1503, 1.7289],
      [0.1913, 0.4544, 0.4519, 0.5535],
      [0.5994, 0.8174, -0.9297, -1.2564]
   ])

Suggestion : 4

A nibabel (and nipy) image is the association of three things:,An affine array that tells you the position of the image array data in a reference space.,The image data array: a 3D or 4D array of image data,An image aligned to this template will therefore have an affine giving the relationship between voxels in the aligned image and the MNI RAS+ space.

>>>
import nibabel as nib
   >>>
   epi_img = nib.load('downloads/someones_epi.nii.gz') >>>
   epi_img_data = epi_img.get_fdata() >>>
   epi_img_data.shape(53, 61, 33)
>>>
import matplotlib.pyplot as plt >>>
   def show_slices(slices):
   ...""
" Function to display row of image slices "
""
...fig, axes = plt.subplots(1, len(slices))
   ...
   for i, slice in enumerate(slices):
   ...axes[i].imshow(slice.T, cmap = "gray", origin = "lower") >>>
   >>>
   slice_0 = epi_img_data[26,: ,: ] >>>
   slice_1 = epi_img_data[: , 30,: ] >>>
   slice_2 = epi_img_data[: ,: , 16] >>>
   show_slices([slice_0, slice_1, slice_2]) >>>
   plt.suptitle("Center slices for EPI image")
>>> anat_img = nib.load('downloads/someones_anatomy.nii.gz') >>>
   anat_img_data = anat_img.get_fdata() >>>
   anat_img_data.shape(57, 67, 56) >>>
   show_slices([anat_img_data[28,: ,: ],
      ...anat_img_data[: , 33,: ],
      ...anat_img_data[: ,: , 28]
   ]) >>>
   plt.suptitle("Center slices for anatomical image")
>>> n_i, n_j, n_k = epi_img_data.shape >>>
   center_i = (n_i - 1) // 2  # // for integer division
   >>>
   center_j = (n_j - 1) // 2
   >>>
   center_k = (n_k - 1) // 2
   >>>
   center_i, center_j, center_k(26, 30, 16) >>>
   center_vox_value = epi_img_data[center_i, center_j, center_k] >>>
   center_vox_value
81.5492877960205...
>>> # Set numpy to print 3 decimal points and suppress small values
   >>>
   import numpy as np >>>
   np.set_printoptions(precision = 3, suppress = True) >>>
   # Print the affine >>>
   epi_img.affine
array([
   [3., 0., 0., -78.],
   [0., 2.866, -0.887, -76.],
   [0., 0.887, 2.866, -64.],
   [0., 0., 0., 1.]
])
>>> M = epi_img.affine[: 3,: 3] >>>
   abc = epi_img.affine[: 3, 3]