convert python map objects to array or dataframe - python-3.x

How can we convert map objects(derived from ndarray objects) to a dataframe or array object in python.
I have a normally distributed data with size 10*10 called a. There is one more data containing 0 and 1 of size 10*10 called b. I want to add a to b if b is not zero else return b.
I am doing it through map. I am able to create the map object called c but can't see the content of it. Can someone please help.
a=numpy.random.normal(loc=0.0,scale=0.001,size=(10,10))
b = np.random.randint(2, size=a.shape)
c=map(lambda x,y : y+x if y!=0 else x, a,b)
a=[[.24,.03,.87],
[.45,.67,.34],
[.54,.32,.12]]
b=[[0,1,0],
[1,0,0],
[1,0,1]]
then c should be as shown below.
c=[[0,1.03,.87],
[1.45,0,0],
[1.54,0,1.12]
]

np.multiply(a,b) + b
should do it
Here is the output
array([[0. , 1.03, 0. ],
[1.45, 0. , 0. ],
[1.54, 0. , 1.12]])

Since, a and b are numpy arrays, there is a numpy function especially for this use case as np.where (documentation).
If a and b are as follows,
a=np.array([[.24,.03,.87],
[.45,.67,.34],
[.54,.32,.12]])
b=np.array([[0,1,0],
[1,0,0],
[1,0,1]])
Then the output of the following line,
np.where(b!=0, a+b, b)
will be,
[[0. 1.03 0. ]
[1.45 0. 0. ]
[1.54 0. 1.12]]

Related

How can I use tf.gather to slice values from the first axis?

I would expect the chunk below to return a tensor with shape (128,64) or (1,128,64), since I am telling it to gather values from the first axis and I
tf.gather(h_states # shape: (3,128,64)
,indices # shape: (128), values are integers between 0 and 2
,axis = 0
,batch_dims=0)
Instead it is returning a (128,128,64) tensor. What am I doing wrong? How could I actually make it select sub-tensors from the first axis?
Thanks
You don't have to use the gather method, slice the tensor is very simple .
yourTensor[ indexYouWant , : , : ] # shape(128,64)
yourTensor[ indexYouWant:indexYouWant+1 , : , : ] # shape(1,128,64)
if you want multiple row (e.g : index 0 and 2),you can use gather method:
tf.gather(yourTensor , indices = [0,2] , axis = 0)

Appending to numpy array within a loop

I really hope to not have missed something, that had been clarified before, but I couldn't find something here.
The task seems easy, but I fail. I want to continuously append a numpy array to another one while in a for-loop:
step_n = 10
steps = np.empty([step_n,1])
for n in range(step_n):
step = np.random.choice([-1, 0, 1], size=(1,2))
#steps.append(step) -> if would be lists, I would do it like that
a = np.append(steps,step)
#something will be checked after each n
print(a)
The output should be ofc of type <class 'numpy.ndarray'> and look like:
[[-1. 0.]
[ 0. 0.]
[-1. -1.]
[ 1. -1.]
[ 1. 1.]
[ 0. -1.]
[-1. 1.]
[-1. 0.]
[ 0. -1.]
[ 1. 1.]]
However the code fails for some (most probably obvious) reasons.
Can someone give me a hint?
import numpy as np
step_n = 10
steps = np.random.choice([-1, 0, 1], size=(1,2))
for n in range(step_n-1):
step = np.random.choice([-1, 0, 1], size=(1,2))
print(steps)
steps = np.append(steps, step, axis=0)
#something will be checked after each n
print(steps)
One of the problems is that your steps variable that is initialized outside the for loop has a different size than each step inside. I changed how you initialized the variable steps, by creating your first step outside of the for loop. This way, your steps variable already has the matching size. But notice you need to reduce 1 iteration in the for loop because of this.
Also, you want to update the steps variable in each for loop, and not create a new variable "a" inside it. In your code, you would just end up with the steps array (that never changes) and only the last step.

Aligning nifti files with different shape and q_offset values in header

I have a whole-body MRI scans with the header below:
{
dim : [ 3 320 260 96 1 0 0 0]
pixdim : [1. 1.40625 1.40625 3. 0.00436 0. 0. 0. ]
qoffset_x : -216.09375
qoffset_y : -178.90625
qoffset_z : -664.5
srow_x : [ 1.40625 0. 0. -216.09375]
srow_y : [ 0. 1.40625 0. -178.90625]
srow_z : [ 0. 0. 3. -664.5]
}
Binary label-maps for different organs in the whole-body MRI scan. I need to merge them together as a single label-map nifty file.
One of the label-map has a different shape and q_offset values in its header that make merging difficult. The header of that label-map nifty file below:
{
dim : [ 3 55 49 28 1 1 1 1]
pixdim : [1. 1.40625 1.40625 3. 1. 1. 1. 1. ]
qoffset_x : 119.41935
qoffset_y : 106.36636
qoffset_z : -503.68216
srow_x : [ -1.40625 0. 0. 119.41935]
srow_y : [ 0. -1.40625 0. 106.36636]
srow_z : [ 0. 0. 3. -503.68216]
}
When I overlay the individual label-map on top of the whole-body MRI scan using 3dSlicer, it overlayed perfectly for the concerned organ, but as the shape is different, once after merging all label-maps, it does not work [ Yellow label-map for Spleen organ].
This is how it looks in 3dSlicer [ Look for Yellow region.].
But the expected area of visualization is in the bottom right of below pic. (Spleen Organ)
As the voxel resolution is the same, I think this has something to do with different q_offset values.
Kindly, let me know if anyone has a solution.
It depends on what your program for viewing / post-processing requires.
Some programs need the resolutions to be the same (which is not true in your case), but then may allow different Q/S-forms (when they are not used).
Others allow you to overlay images with different resolutions, but then rely on the Q/S forms to position the images in the view box.
One interesting thing in your nifti headers is that the x and y voxel sizes in the S-form are positive in the scan and negative in the labels.
That means:
increasing x indices go from left to right in the MR scan
increasing x indices go from right to left in the labels
and
increasing y indices go from front to back in the MR scan
increasing y indices go from back to front in the labels
As your viewer seems to take the Q/S-forms into account, that would mean that the voxel data themselves are swapped in both directions. But that also means that the centres of gravity may need adjusting (in one case: offsets are from the left/front, in the other case from the right/back).
You can test that with a copy of your file where the new offsets are changed. The S-form does look like the labels have been aligned (the offsets are greater than the extents of the bounding box) but maybe not with a tool that handles images with different LR and AP orientations well.

Complete values are not writing to the file using Python

My idea is to write some large number of bits to a file (almost 64*4800 bits). It is writing but not all the bits.
The console output looks like
[1. 1. 0. ... 1. 0. 1.]
If I decrement the number of bits to be saved then it will work.
I will paste my code here. This code is sampling the analog to digital
y= function(x) # Inside this function I am generating binary values and stored to y
################ y is in numpy.ndarray form
################ x is a sine wave
f=open('filename.txt',"w+")
f.write(str(y)) #we have to convert the numpy.ndarray to str.
f.close()
when I open my filename.txt file it is showing the binary values as
[1. 1. 0. ... 1. 0. 1.]
which is same as in the console.
Please help me to resolve this issue. I need all the bits (64*4800) to be saved inside the file
Try converting your numpy array to a list first:
y = function(x) # Inside this function I am generating binary values and stored to y
################ y is in numpy.ndarray form
################ x is a sine wave
y_list = y.tolist() # Convert to python list
# use the with context manager and you don't need to call .close() explicitly
with open('filename.txt',"w+") as f:
f.write(str(y_list)) #we have to convert the numpy.ndarray to a list and then to str(y_list) which will write the entire bits.

Finding more indices in a list close to zero

I have a list of values, which represents a damping function when this is plotted (so a form of a sinusoide). This function passes the y=0 thus several times until it levels out on y=0. I need to find the index at the moment when the function passes zero for the third time.
All values are floats, so I have a function that finds the index closest to zero:
def find_index(list_, value):
array = np.asarray(list_)
idx = (np.abs(array - value)).argmin()
return idx
Where 'list_' is the list and 'value' is zero.
This function does work, but it can only retrieve the index of the first moment the damping function (and thus the list) is closest to zero. Meaning that it will show an index of zero (because the damping function starts at zero). However, I need the index of the third time when it is closest to zero.
How can I obtain the index of the third time it will be closest to zero, instead of the first time?
You are looking for a change in the sign.
import numpy as np
x = np.array([10.0, 1.0, -1.0, -2.0, 1.0, 4.0])
y = np.sign(x) # -1 or 1
print(y)
>>> [ 1. 1. -1. -1. 1. 1.]
If you calculate the difference between consecutive elements using np.diff it will be either -2 or 2, both are boolean True.
>>> [ 0. -2. 0. 2. 0.]
Now get the indices of them using np.nonzero, which returns a tuple for each dimension. Pick the first one.
idx = np.nonzero(np.diff(y))[0]
print(idx)
>>> [1 3]

Resources