how to use values of a pandas DataFrame as numpy array index - python

I have a pandas dataFrame like this.
The X, Y, Z are they (x,y,z) coordinates that represent a point inside a cube of side-length 255.
I want to create a numpy array/dataFrame from this, whose index will be the (x,y,z) coordinates and value is the intensity.
the output should be
data[133,55,250] = 8
data[133,61,254] = 21
...
I tried something like this
data = np.zeros((255,255,255), dtype=np.int)
index = np.array((temp['X'], temp['Y'], temp['Z']))
but returned index is a (3,15) array.
I want a index where
data[index] = intensity
will give me my result.

Instead of
index = np.array((temp['X'], temp['Y'], temp['Z']))
you could use integer array indexing to perform the assignment:
data = np.zeros((256, 256, 256), dtype=np.int)
data[temp['X'], temp['Y'], temp['Z']] = temp['intensity']

Related

Changing the value of values after a particular index along one axis in a 3D numpy array

I have a 3d array of format given below.
The below is the one sample of the 3D array, like it , it contain more than 1000.
sample
shape of the 3D array is (1000 x 10 x 5)
The image contain one element (10 x 5)
I want to change the value to 0 after the 3rd one on the last value
check the figure below
desired
I want to change like it for all the 1000 elements in my array.
Is there a better way to do it other than using "for loop" ?
import numpy as np
# Your array here:
arr = np.arange(50000).reshape(1000, 10, 5)
# Solution:
arr[:, 3:, -1] = 0

How to sort each row of a 3D numpy array by another 2D array?

I have a 2D numpy array of 2D points:
np.random.seed(0)
a = np.random.rand(3, 4, 2) # each value is a 2D point
I would like to sort each row by the norm of every point
norms = np.linalg.norm(a, axis=2) # shape(3, 4)
indices = np.argsort(norms, axis=0) # indices of each sorted row
Now I would like to create an array with the same shape and values as a. that will have each row of 2D points sorted by their norm.
How can I achieve that?
I tried variations of np.take & np.take_along_axis but with no success.
for example:
np.take(a, indices, axis=1) # shape (3,3,4,2)
This samples a 3 times, once for each row in indices.
I would like to sample a just once. each row in indices has the columns that should be sampled from the corresponding row.
If I understand you correctly, you want this:
norms = np.linalg.norm(a,axis=2) # shape(3,4)
indices = np.argsort(norms , axis=1)
np.take_along_axis(a, indices[:,:,None], axis=1)
output for your example:
[[[0.4236548 0.64589411]
[0.60276338 0.54488318]
[0.5488135 0.71518937]
[0.43758721 0.891773 ]]
[[0.07103606 0.0871293 ]
[0.79172504 0.52889492]
[0.96366276 0.38344152]
[0.56804456 0.92559664]]
[[0.0202184 0.83261985]
[0.46147936 0.78052918]
[0.77815675 0.87001215]
[0.97861834 0.79915856]]]

Creating new 2D array from a slice of 3D array in python?

I have a 3D array [256,256,450] that I would like to fetch a 2D array from a cross section along the z axis. The new 2D array should start at z=0 at the top and have the values across some i'th y slice for x =0 to x=255. Then the next row in the new 2D array should be the same for z=1, and so on until z=449. How can this be done?
Use NumPy's NDArray class and slicing syntax.
import numpy as np
my_array = np.zeros([256, 256, 450]) # 256x256x450 array
... # Do whatever you want to do to load data in
x_slice = my_array[0,:,:] # A 256x450 array, the first element in x
y_slice = my_array[:,0,:] # A 256x450 array, the first element in y
y_slice = my_array[:,99,:] # A 256 x 450 array, the 100th element in y
import numpy as np
array_3d = np.ones((256, 256, 450))
y_layer = 24 # arbitrary y layer
array_2d = array_3d[:, y_layer, :]

2d array compare to 1d array returns 2d array

I am trying to compare a 1D array element-wise to a 2D array, and returns the elements of the 2D array which fulfils the condition in a 2D array form without using a for loop. Preferably using numpy or quicker method.
a = range(1,10)
Tna = np.random.choice(a, size=[250,10,1000], replace=True)
sum_Ta = np.sum(Tna, axis = 1)
percent = np.percentile(sum_Ta, 5, axis =0)
Now I would like to get a 2D array which contains the elements of sum_Ta if the elements are smaller the percent. Such that 250 elements of sum_Ta are comparing with 1 element of percent for 1000 times. Originally I can do, ES = sum_Ta[sum_Ta < percent[:,None]], but it only gives me a 1D array, not a 2D array.
Assuming you mean that for each row, you want the element of the row to be included if it is less than the percentage associated with its column.
Try the following:
mask = sum_Ta < (percent * np.ones((250,1)))
ES = np.zeros((250, 1000))
ES[mask] = sum_Ta[mask]

removing entries from a numpy array

I have a multidimensional numpy array with the shape (4, 2000). Each column in the array is a 4D element where the first two elements represent 2D positions.
Now, I have an image mask with the same shape as an image which is binary and tells me which pixels are valid or invalid. An entry of 0 in the mask highlights pixels that are invalid.
Now, I would like to do is filter my first array based on this mask i.e. remove entries where the position elements in my first array correspond to invalid pixels in the image. This can be done by looking up the corresponding entries in the mask and marking those columns to be deleted which correspond to a 0 entry in the mask.
So, something like:
import numpy as np
# Let mask be a 2D array of 0 and 1s
array = np.random.rand(4, 2000)
for i in range(2000):
current = array[:, i]
if mask[current[0], current[1]] <= 0:
# Somehow remove this entry from my array.
If possible, I would like to do this without looping as I have in my incomplete code.
You could select the x and y coordinates from array like this:
xarr, yarr = array[0, :], array[1, :]
Then form a boolean array of shape (2000,) which is True wherever the mask is 1:
idx = mask[xarr, yarr].astype(bool)
mask[xarr, yarr] is using so-called "integer array indexing".
All it means here is that the ith element of idx equals mask[xarr[i], yarr[i]].
Then select those columns from array:
result = array[:, idx]
import numpy as np
mask = np.random.randint(2, size=(500,500))
array = np.random.randint(500, size=(4, 2000))
xarr, yarr = array[0, :], array[1, :]
idx = mask[xarr, yarr].astype(bool)
result = array[:, idx]
cols = []
for i in range(2000):
current = array[:, i]
if mask[current[0], current[1]] > 0:
cols.append(i)
expected = array[:, cols]
assert np.allclose(result, expected)
I'm not sure if I'm reading the question right. Let's try again!
You have an array with 2 dimensions and you want to remove all columns that have masked data. Again, apologies if I've read this wrong.
import numpy.ma as ma
a = ma.array((([[1,2,3,4,5],[6,7,8,9,10]]),mask=[[0,0,0,1,0],[0,0,1,0,0]])
a[:,-a.mask.any(0)] # this is where the action happens
the a.mask.any(0) identifies all columns that are masked into a Boolean array. It's negated (the '-' sign) because we want the inverse, and then it uses that array to remove all masked values via indexing.
This gives me an array:
[[1 2 5],[6 7 10]]
In other words, the array has all removed all columns with masked data anywhere. Hope I got it right this time.

Categories

Resources