Comparing elements of the same multi dimensional array - python

So I do have an multi dimensional array in this format:
Cjk = [[81 51 31] [82 47 54] [34 55 64] [96 73 43]];
How can I get the minimum values on each index of the arrays contained.
I want this output:
34 47 31 # these are the minimum values compared to each one values of the same index
I have tried some methods but they were unsucesfully because I had to work with I and J because the array Cjk will get more values in time so it needs to be scalable

You want to find the minimum in each column. You can use zip here.
Cjk = [[81 51 31] [82 47 54] [34 55 64] [96 73 43]]
min_cols=[min(lst) for lst in zip(*Cjk)]
# [34, 47, 31]

You can do this,
In [21]: list(map(lambda x:min(x),zip(*Cjk)))
Out[21]: [34, 47, 31]

You can import numpy and find minimums and maximums inrows and columns of the matrix, using axis parameter.
Like in this example:
import numpy as np
>>> x = -np.matrix(np.arange(12).reshape((3,4))); x
matrix([[ 0, -1, -2, -3],
[ -4, -5, -6, -7],
[ -8, -9, -10, -11]])
>>> x.min()
-11
>>> x.min(0)
matrix([[ -8, -9, -10, -11]])
>>> x.min(1)
matrix([[ -3],
[ -7],
[-11]])
Check this https://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.min.html

Related

slicing a 3d numpy array with index as arrays and reshape

I have a 3d array of shape (3, 5, 5). I need to slice using different indices along the 2nd and 3rd axis for each of the 3 elements
ts = np.arange(25*3).reshape(3,5,5)
print(ts)
newr1 = np.array([1,0,2])
newr2 = np.array([3,2,4])
newc1 = np.array([1,2,0])
newc2 = np.array([3,4,2])
I want something like ts[:, newr1:newr2, newc1:newc2] but this type of slicing only works for scalar indexes. The output should look like below. Please advise
array([[[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]],
[[27, 28, 29],
[32, 33, 34],
[37, 38, 39]],
[[60, 61, 62],
[65, 66, 67],
[70, 71, 72]]])
OK, my curiosity got the better of me. I'll work out an answer even though you didn't provide as much information as you should have.
In [10]: ts = np.arange(25*3).reshape(3,5,5)
...: print(ts)
...: newr1 = np.array([1,0,2])
...: newr2 = np.array([3,2,4])
...:
...: newc1 = np.array([1,2,0])
...: newc2 = np.array([3,4,2])
...:
[[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
[[25 26 27 28 29]
[30 31 32 33 34]
[35 36 37 38 39]
[40 41 42 43 44]
[45 46 47 48 49]]
[[50 51 52 53 54]
[55 56 57 58 59]
[60 61 62 63 64]
[65 66 67 68 69]
[70 71 72 73 74]]]
My guess is that what you want is:
In [11]: for i in range(3):
...: x = ts[i,newr1[i]:newr2[i],newc1[i]:newc2[i]]
...: print(x)
...:
[[ 6 7]
[11 12]]
[[27 28]
[32 33]]
[[60 61]
[65 66]]
OK, that's close, though you didn't treat the end points of slices right.
linspace is able to generate 'slices/aranges', for arrays of inputs:
In [13]: np.linspace(newr1,newr2,3)
Out[13]:
array([[1., 0., 2.],
[2., 1., 3.],
[3., 2., 4.]])
trying to use such matrices as index gives an error:
In [14]: I=np.linspace(newr1,newr2,3)
In [15]: J=np.linspace(newc1,newc2,3)
In [16]: ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
Traceback (most recent call last):
File "<ipython-input-16-5bc9e51832b8>", line 1, in <module>
ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
IndexError: arrays used as indices must be of integer (or boolean) type
In [17]: I=np.linspace(newr1,newr2,3).astype(int)
In [18]: J=np.linspace(newc1,newc2,3).astype(int)
In [19]: I
Out[19]:
array([[1, 0, 2],
[2, 1, 3],
[3, 2, 4]])
In [20]: J
Out[20]:
array([[1, 2, 0],
[2, 3, 1],
[3, 4, 2]])
After a couple of mistakes, I arrived at:
In [23]: ts[np.arange(3)[:,None,None], I.T[:,:,None], J.T[:,None,:]]
Out[23]:
array([[[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]],
[[27, 28, 29],
[32, 33, 34],
[37, 38, 39]],
[[60, 61, 62],
[65, 66, 67],
[70, 71, 72]]])
So if the slice sizes are consistent across 'planes', we can make this selection with an appropriate set of index arrays.

Deleting specific numbers from a (2,60) numpy array?

I have a numpy array that has a shape of (2,60). Some of the numbers in the first row exceed 30 and I want to filter columns for which the value of the first row is less than 30.
I tried array = array[array < 30] #but that doesn't work
An example of my array is
array = np.array([[30,40,12,12,10,2,30,40],[2,5,75,67,89,5,3,4]])
Expected output:
array = [[12 12 10 2]
[75 67 89 5]]
You are looking for this:
array[:,array[0]<30]
output:
array([[12, 12, 10, 2],
[75, 67, 89, 5]])

How to find difference between all integers in an array

Can someone point me in the right direction to accomplish the following. I would really appreciate it.
Given the following column.
111
108
106
107
109
130
I would like to take the first number(111) and find and print the difference between the rest of the values in the order they appear.
I would then like to repeat the process starting on the second position(108) until all rows have looped through to the end.
And lastly I would like to display the biggest difference and row# from the results.
Expected output is something along these lines
Start bigest-difference row/positioning
111 19 5
108 22 5
106 24 5
107 23 5
109 24 5
130 24 2
You could use broadcasting:
import numpy as np
data = np.array([111, 108, 106, 107, 109, 130])
data - data[:, None]
# array([[ 0, -3, -5, -4, -2, 19],
# [ 3, 0, -2, -1, 1, 22],
# [ 5, 2, 0, 1, 3, 24],
# [ 4, 1, -1, 0, 2, 23],
# [ 2, -1, -3, -2, 0, 21],
# [-19, -22, -24, -23, -21, 0]])

Cummulative addition in a loop

I am trying to cummatively add a value to the previous value and each time, store the value in an array.
This code is just part of a larger project. For simplicity i am going to define my variables as follows:
ele_ini = [12]
smb = [2, 5, 7, 8, 9, 10]
val = ele_ini
for i in range(len(smb)):
val += smb[i]
print(val)
elevation_smb.append(val)
Problem
Each time, the previous value stored in elevation_smb is replaced by the current value such that the result i obtain is:
elevation_smb = [22, 22, 22, 22, 22, 22]
The result i am expecting however is
elevation_smb = [14, 19, 26, 34, 43, 53]
NOTE:
ele_ini is a vector with n elements. I am only using 1 element just for simplicity.
Don use loops, because slow. Better is fast vectorized solution below.
I think need numpy.cumsum and add vector ele_ini for 2d numpy array:
ele_ini = [12, 10, 1, 0]
smb = [2, 5, 7, 8, 9, 10]
elevation_smb = np.cumsum(np.array(smb)) + np.array(ele_ini)[:, None]
print (elevation_smb)
[[14 19 26 34 43 53]
[12 17 24 32 41 51]
[ 3 8 15 23 32 42]
[ 2 7 14 22 31 41]]
It seems vector in your case is using pointers. That's why it is not creating new values. Try adding copy() which copies the value.
elevation_smb.append(val.copy())
Do with reduce,
In [6]: reduce(lambda c, x: c + [c[-1] + x], smb, ele_ini)
Out[6]: [12, 14, 19, 26, 34, 43, 53]

What does scipy.signal.convolve2d calculate? [duplicate]

This question already has answers here:
scipy convolve2d outputs wrong values
(2 answers)
Closed 6 years ago.
I am currently a bit confused by the output of
#!/usr/bin/env python
import scipy.signal
image = [[1, 2, 3, 4, 5, 6, 7],
[8, 9, 10, 11, 12, 13, 14],
[15, 16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27, 28],
[29, 30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41, 42],
[43, 44, 45, 46, 47, 48, 49]]
filter_kernel = [[-1, 1, -1],
[-2, 3, 1],
[2, -6, 0]]
res = scipy.signal.convolve2d(image, filter_kernel,
mode='same', boundary='fill', fillvalue=0)
print(res)
It was
[[ -2 -8 -7 -6 -5 -4 28]
[ 3 -7 -10 -13 -16 -19 14]
[ -18 -28 -31 -34 -37 -40 0]
[ -39 -49 -52 -55 -58 -61 -14]
[ -60 -70 -73 -76 -79 -82 -28]
[ -81 -91 -94 -97 -100 -103 -42]
[-101 -61 -63 -65 -67 -69 -57]]
I expected the top left element to be 3*1 + 1*2 + (-6) *8 + 0*9 = -43 (ommitting the padded zeros).
I thought this would expand the matrix image \in R^{7x7} to R^{9x9} by adding one 0 to the left / right and top / bottom. Then I thought the filter_kernel would be calculated by "sliding" it over the image. At each position, the numbers from the image are point-wise multiplied with the numbers from the kernel. The nine products are the summed up and written into res.
However, it is -2. Obviously, something different happens.
Convolution reverses the direction of one of the functions it works on. Check The definition on Wikipedia: one function is parameterized with τ and the other with -τ. The same applies to 2D convolution.
You need to mirror the kernel to get the expected resut:
filter_kernel = [[0, -6, 2],
[1, 3, -2],
[-1, 1, -1]]
res = scipy.signal.convolve2d(image, filter_kernel,
mode='same', boundary='fill', fillvalue=0)
print(res[0, 0])
# -43

Categories

Resources