I have a rgb image, for example
img_rgb[:,:,0] = [ 125 160; 130 125];
img_rgb[:,:,1] = [ 125 160; 130 125];
img_rgb[:,:,2] = [ 125 160; 130 125];
and a mask boolean image whose size equals the size of img_rgb e.g
mask[:,:] = [ 1 0; 0 1]
for every zero value of mask, I would like to associate a nan value in the img-rgb, thus obtaining the following
img_rgb[:,:,0] = [ 125 nan; nan 125]
img_rgb[:,:,1] = [ 125 nan; nan 125]
img_rgb[:,:,2] = [ 125 nan; nan 125]
Since my image array is really big (length size 10000px) I would like to do that as fast as possible and thus avoiding a double for cycle. In Matlab I would use the logical operator
img_rgb(repmat(mask,1,1,3)==0)=nan;
how can I do something similar in python? python v.2.7
Thanks in advance
When you use numpy arrays, you can use boolean indexing similar to Matlab in python.
Broadcasting will take care of the repmat for you. So you can do just:
import numpy as np
img_rgb[mask == 0] = np.Nan
Related
I try to create a matrix 100x100 which should have in each row next ordinal number like below:
I created a vector from 1 to 100 and then using for loop I copied this vector 100 times. I received an array with correct data so I tried to sort arrays using np.argsort, but it didn't worked as I want (I don't know even why there are zeros in after sorting).
Is there any option to get this matrix using another functions? I tried many approaches, but the final layout was not what I expected.
max_x = 101
z = np.arange(1,101)
print(z)
x = []
for i in range(1,max_x):
x.append(z.copy())
print(x)
y = np.argsort(x)
y
argsort returns the indices to sort by, that's why you get zeros. You don't need that, what you want is to transpose the array.
Make x a numpy array and use T
y = np.array(x).T
Output
[[ 1 1 1 ... 1 1 1]
[ 2 2 2 ... 2 2 2]
[ 3 3 3 ... 3 3 3]
...
[ 98 98 98 ... 98 98 98]
[ 99 99 99 ... 99 99 99]
[100 100 100 ... 100 100 100]]
You also don't need to loop to copy the array, use np.tile instead
z = np.arange(1, 101)
x = np.tile(z, (100, 1))
y = x.T
# or one liner
y = np.tile(np.arange(1, 101), (100, 1)).T
import numpy as np
np.asarray([ (k+1)*np.ones(100) for k in range(100) ])
Or simply
np.tile(np.arange(1,101),(100,1)).T
In Python, is there a way to generate a 2d array using numpy with random integer entries without specifying either the low or high?
I tried mat = np.random.randint(size=(3, 4)) but it did not work.
Assuming you don't want to specify the min or max values of the array, one can use numpy.random.normal
np.random.normal(mean, standard deviation, (rows,columns))
And then round it with astype(np.int), as
>>> import numpy as np
>>> mat = (np.random.normal(1, 3, (3,4))).astype(np.int)
[[ 0 0 0 -1]
[ 0 5 0 0]
[-5 1 2 2]]
Please note that the output may vary, as the values are random.
If you want to specify the min and max values, there are various ways of doing that, such as
mat = (np.random.random((3,4))*10).astype(np.int) # Random ints between 0 and 10
or
mat = np.random.randint(1,5, size=(3,4)) # Random ints between 1 and 5
And more.
I want to train an LSTM neural network and need to reshape a 2-dimensional dataframe / numpy array into a 3-dimensional array for this task. My dataframe has the following structure where it is important to emphasize that each member may have a variable number of rows / transactions:
Member order_day order amount
a 100 150
a 107 140
a 120 160
b 85 90
b 89 84
c 135 110
I now need to transform it into a 3d array with dimensions (# of members, max # of transactions for a single member, # of features) so here (3, 3, 2). The matrices of the members that have fewer than 3 transactions, in this example, need to be pre- or post-sequence padded with an arbitrary number below 0 which can then be masked during training.
The answer to this question solves part of the problem by showing how a 3d array with variable number of rows per matrix can be padded. It proposes to use the following code where X is the 3d array:
Xpad = np.full((N, max_seq_len, dimension), fill_value=special_value)
for s, x in enumerate(X):
seq_len = x.shape[0]
Xpad[s, 0:seq_len, :] = x
However, I am unable to figure out how to create the 3d array as a collection of 2d member arrays.
For clarity, the 3d matrix that I am looking for would look like this in case of pre-sequence padding and when -10 is used as the arbitrary negative number:
[[100, 150
107, 140
120, 160],
[-10, -10
85 , 90
89 , 84],
[-10, -10
-10, -10
135, 110]]
Thanks for helping out!
I have a list of index stored in a list of tuples:
index=[(0,0), (0,1), (1,0), (1,1) ....]
These indexes will be used to calculate energy in an image im (a numpy array) in the following formula:
(1-im[0,0])^2+(1-im[0,1])^2+....
im here is a two dimensional numpy array. Here's an example of im:
im=Image.open('lena_noisy.png')
im=numpy.array(im)
print im
[[168 133 131 ..., 127 213 107]
[174 151 111 ..., 191 88 122]
[197 173 143 ..., 182 153 125]
...,
[ 34 15 6 ..., 111 95 104]
[ 37 15 57 ..., 121 133 134]
[ 49 39 58 ..., 115 74 107]]
How to use map function of list to perform this calculation?
If you break index into two tuples, xidx and yidx then you can use fancy indexing to access all the im values as one numpy array.
Then the calculation becomes simple to express, and faster than doing a Python loop (or list comprehension):
import numpy as np
xidx, yidx = zip(*index)
print(((1-im[xidx, yidx])**2).sum())
import numpy as np
import scipy.misc as misc
im = misc.lena()
n = min(im.shape)
index = np.random.randint(n, size = (10000,2)).tolist()
def using_fancy_indexing(index, im):
xidx, yidx = zip(*index)
return (((1-im[xidx, yidx])**2).sum())
def using_generator_expression(index, im):
return sum(((1 - im[i[0], i[1]]) ** 2) for i in index)
Here is a comparison using timeit:
In [27]: %timeit using_generator_expression(index, im)
100 loops, best of 3: 17.9 ms per loop
In [28]: %timeit using_fancy_indexing(index, im)
100 loops, best of 3: 2.07 ms per loop
Thus, depending on the size of index, using fancy indexing could be 8x faster than using a generator expression.
Like this, using a generator expression:
sum((1-im[i][j])**2 for i, j in index)
That is, assuming that im is a two-dimensional list and index is a list of coordinates in im. Notice that in Python, a two-dimensional list is accessed like this: m[i][j] and not like this: m[i,j].
Using sum and a generator expression:
sum(((1 - im[i[0], i[1]]) ** 2) for i in index)
If index is also a numpy array you can use the array as an index:
sum(((1 - im[i]) ** 2) for i in index)
I have a NumPy array of size 94 x 155:
a = [1 2 20 68 210 290..
2 33 34 55 230 340..
.. .. ... ... .... .....]
I want to calculate the range of each row, so that I get 94 ranges in a result. I tried looking for a numpy.range function, which I don't think exists. If this can be done through a loop, that's also fine.
I'm looking for something like numpy.mean, which, if we set the axis parameter to 1, returns the mean for each row in the N-dimensional array.
I think np.ptp might do what you want:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.ptp.html
r = np.ptp(a,axis=1)
where r is your range array.
Try this:
def range_of_vals(x, axis=0):
return np.max(x, axis=axis) - np.min(x, axis=axis)