Getting max ,min and last index value within multidimensional arrays - python

The output of result are 3 arrays that are 2 dimensional with lengths that are getting decremented by one. I want to write a code that gets the ending index value last_incs, max value maxs and the minimum values mins. It should iterate through all the rows of each of the 2nd dimensional array, for example the result output for [-3,-1,-2,1] is array([array([ 0., 0., 0., 25.]),array([ 0,0, 33.33333333]), array([ 0., 50.]),array([100.])], dtype=object). The maximum values corresponding to each of these sub arrays are as follows: [25.0, 33.33333333333333, 50.0, 100.0] which is shown in the Expected Outputs below in Max:. How would I be able to do this?
import numpy as np
def run(*args):
result = np.array([np.array([((arr[i:] > 0).cumsum()/ np.arange(1, len(arr[i:])+1) * 100) for i in range(len(arr))],dtype=object) for arr in args], dtype=object)
#print(result)
last_inc = result[-1]
maxs = np.max(result)
mins = np.min(result)
run(np.array([12,12,-3,-1,2,1]), np.array([-3,-1,-2,1]), np.array([12,-12]))
Expected Output:
last incs: [array([66.66666666666666, 60.0, 50.0, 66.66666666666666, 100.0, 100.0],
dtype=object)
array([25.0, 33.33333333333333, 50.0, 100.0], dtype=object)
array([50.0, 0.0], dtype=object)]]
mins: [array([50.0, 33.33333333333333, 0.0, 0.0, 100.0, 100.0], dtype=object)
array([0.0, 0.0, 0.0, 100.0], dtype=object)
array([50.0, 0.0], dtype=object)]
maxs: [array([100.0, 100.0, 50.0, 66.66666666666666, 100.0, 100.0], dtype=object)
array([25.0, 33.33333333333333, 50.0, 100.0], dtype=object)
array([100.0, 0.0], dtype=object)]

The following code gets your needed outputs, use it in your function:
size = np.empty(0)
for i in result:
size = np.append(size, np.size(i))
results_arrays = np.empty(0)
for i in np.hstack(result).T:
last_incs = np.float64(np.vstack(i)[-1])
maxs = np.max(np.vstack(i))
mins = np.min(np.vstack(i))
results_arrays = np.append(results_arrays, np.array([last_incs, maxs, mins]))
last_incs = np.array_split(results_arrays[0::3], np.cumsum(size, axis=0).astype(int), axis=0)[:-1]
maxs = np.array_split(results_arrays[1::3], np.cumsum(size, axis=0).astype(int), axis=0)[:-1]
mins = np.array_split(results_arrays[2::3], np.cumsum(size, axis=0).astype(int), axis=0)[:-1]

Related

How to find the maximum of sublists in arbitrary nested list?

I have a list C11 containing many sublists. I want to find the maximum element of each sublist. I present the current and expected outputs.
C11 = [[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
for i in range(0,len(C11)):
C2 = max(C11[i])
print(C2)
The current output is
[[353.856161, 0.0, 0.0], [0.0, 294.983702, 126.991664]]
The expected output is:
[[[353.856161],[282.754301]], [[294.983702]]]
In case the depth is completely arbitrary and you want to keep the same nesting structure in the output, here is a recursive function that keeps going in levels until reaching a "leaf" (list with values and not lists) and takes the maximums:
def get_max(l):
res = []
if isinstance(l[0], list):
for sub in l:
res.append(get_max(sub))
else:
res.append(max(l))
return res
print(get_max([[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]))
Will give:
[[[353.856161], [282.754301]], [[294.983702]]]
Use this function in case the nesting-depth of the list is variable.
C11=[[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
def find_max(ls: list) -> list:
# does the list contain only numbers?
if all((isinstance(x, float) for x in ls)):
# if yes return simple max
return [max(ls)]
else:
# apply the function one level deeper
return [find_max(x) for x in ls]
print(find_max(C11))
List Comprehension
Code:-
C11=[[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
res=[[[max(sublist)] for sublist in lis] for lis in C11]
print(res)
Output:
[[[353.856161], [282.754301]], [[294.983702]]]
Here is a quick recursive generalized approach. Should work with any level of varying nesting.
c11 = [[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
result = []
def traverse(arr, result):
if len(arr) > 0:
if type(arr[0]) is list:
# check if item inside list is another list
for i in arr:
result = traverse(i, result)
else:
# if its a list of number, get the max and add it to result
result.append(max(arr))
return result
print(traverse(c11, result))
Using recursive is the best option. Recursive works for any length of list. Used a initial validation to check if list element is empty.
Code:
check=[[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
def recursive_max(lst):
if len(lst) == 0:
return []
if isinstance(lst[0], list):
min_val = []
for val in lst:
min_val.append(recursive_max(val))
return min_val
else:
return [max(lst)]
print(recursive_max(check))
Output:
[[[353.856161], [282.754301]], [[294.983702]]]
C11 array is multi dimension array need put in nested loop
C11 = [[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
for i in range(0, len(C11)):
for j in range(0, len(C11[i])):
C2 = max(C11[i][j])
print(C2)
Output
I have assumed that the depth of the list is random.
I have used a recursive approach to replace a last-level list with a list of its maximum value.
def recurse(l):
for index in range(len(l)):
if type(l[index]) == list:
l[index] = recurse(l[index])
else:
l = [max(l)]
return l
return l
Example:
l = [[5,3,8], [1,2,4], [[[2,4],[11,12]],[5,9]]]
recurse(l)
print(l)
Output:
[[8], [4], [[[4], [12]], [9]]]
Your Example:
C11=[[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
recurse(C11)
print(C11)
Output:
[[[353.856161], [282.754301]], [[294.983702]]]
Note: The function updates the list inplace so if you want to restore the list, use a copy of the old list.
Code:
C11=[[[353.856161, 0.0, 0.0], [0.0, 0.0, 282.754301, 0.0]], [[0.0, 294.983702, 126.991664]]]
C2=[]
for i in range(0,len(C11)):
C2.insert(i, [])
for j in range(0,len(C11[i])):
C2[i].insert(j, [])
C2[i][j].insert(0, max(C11[i][j]))
print(C2)
Output:
[[[353.856161], [282.754301]], [[294.983702]]]

Dividing certain members of a list in python

I have a matrix formed by a list of lists and I want to divide each member of the second half of each sublist by the integer in the first 3 members of each sublist. Here is my code:
def matrix():
a=[[12.0, 0.0, 0.0, 12, 156, -108], [0.0, 2.667, 0.0, -5.333, -77.333, 53.333], [0.0, 0.0, -0.0937, -0.0937, -1.4687, 1.0]]
for i in range(len(a)):
a[i] = [v/a[i][i] for v in a[i]]
return a
However, this code divides each entire sublist by the integer found in the first half of each sublist which gives me this output:
[[1.0, 0.0, 0.0, 1.0, 13.0, -9.0], [0.0, 1.0, 0.0, -1.9996250468691417, -28.996250468691414, 19.99737532808399], [-0.0, -0.0, 1.0, 1.0, 15.674493062966913, -10.672358591248665]]
I only want the second part of each sublist divided, not the first half. I need to obtain this output, as you can see the first 3 integers of each sublist must stay the same:
[[12,0,0,1,13,-9],[0,2.667,0,-2,-29,20],[0,0,-0.09375,1,15.6667,-10.6667]]
You can split up your logic into two steps:
Find the integer in the first three numbers.
Divide the second half of each sublist by that number.
def matrix():
a = [[12.0, 0.0, 0.0, 12, 156, -108],
[0.0, 2.667, 0.0, -5.333, -77.333, 53.333],
[0.0, 0.0, -0.0937, -0.0937, -1.4687, 1.0]]
for i in range(len(a)):
divisor = 0
for j in range(3):
if a[i][j]:
divisor = a[i][j]
break
for j in range(len(a[i]) // 2, len(a[i])):
a[i][j] = a[i][j] / divisor
return a
print(matrix())
Output:
[[12.0, 0.0, 0.0, 1.0, 13.0, -9.0], [0.0, 2.667, 0.0, -1.9996250468691417, -28.996250468691414, 19.99737532808399], [0.0, 0.0, -0.0937, 1.0, 15.674493062966913, -10.672358591248665]]

How to find and pull values at specific indices of several Numpy arrays?

I have a 1D numpy array of specific values:
array_1 = [1.0, 3.0, 7.0, 9.0, 6.0]
These values can be found in a second 1D numpy array, at varying indices:
array_2 = [0.0, 1.0, 12.0, 16.0, 3.0, 7.0, 25.0, 9.0, 1.0, 4.0, 6.0]
I want to pull values from a third 1D numpy array, the same size as array_2, based on the location of the values given in array_1 in array_2:
array_3 = [123.6, 423.4, 12.4, 14.5, 25.6, 67.8, 423.5, 52.3, 32.4, 87.9, 78.1]
So, in the example above, because the values of array_1 are found in the following places in array_2:
[0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1]
I therefore want to pull the values in those same indices from array_3. In other words, I want to be left with the following array_4:
array_4 = [423.4, 25.6, 67.8, 52.3, 78.1]
What's the best way to go about doing this?
You can try np.intersect1d:
_,_,idx = np.intersect1d(array_1, array_2, return_indices=True)
out = np.array(array_3)[sorted(idx)]
Output out:
array([423.4, 25.6, 67.8, 52.3, 78.1])
A non numpy way is
array_4 = []
for i in range(len(array_2)):
if array_2[i] in array_1:
array_4.append(array_3[i])
print(array_4)
Here is another way to do it:
indexes = np.where(array_2 == array_1[:,np.newaxis])
array_4 = array_3[indexes[1]]
print(array_4)
result:
[423.4 32.4 25.6 67.8 52.3 78.1]
Using np.unique
unq,idx,inv = np.unique(np.concatenate([array_2,array_1]),return_index=True,return_inverse=True)
poss = idx[inv[len(array_2):]]
np.array(array_3)[poss]
# array([423.4, 25.6, 67.8, 52.3, 78.1])

Build a dataframe from a filtered list of tuple

I have a two lists
kuid -> ['LOdRTFfn', 'Lckq4LkU', 'LcsYHodm']
And NN that is a list of tuple where the first element is a list of indexs of kuid and the other element is an array of values
NN -> [([0, 1, 2], [0.0, 1.2, 1.4]), ([1, 0, 2], [0.0, 1.4, 1.4]), ([2, 0, 1], [0.0, 1.1, 1.4])]
I'd like to keep only the indexes where the values are less then 1.3 for example:
[([0, 1], [0.0, 1.2]), ([1], [0.0]), ([2, 0], [0.0, 1.1])]
and then get the correct value of kuid and build a dataframe:
kuid la lametric
0 LOdRTFfn [LOdRTFfn, Lckq4LkU] [0.0, 1.2]
1 Lckq4LkU [Lckq4LkU] [0.0]
2 LcsYHodm [LcsYHodm, LOdRTFfn] [0.0, 1.1]
Is it possible to do this with list of comprehensions (or other fast solution) avoiding looping? The array could be very large....
Thank you
Here's one way
In [1789]: df = pd.DataFrame(dict(kuid=kuid, NN=[np.array(x) for x in NN]))
In [1790]: df['lametric'] = df.NN.apply(lambda x: x[1][x[1] < 1.3])
In [1791]: df['la'] = df.NN.apply(lambda x: [kuid[int(i)] for i in x[0][x[1] < 1.3]])
In [1792]: df
Out[1792]:
NN kuid lametric \
0 [[0.0, 1.0, 2.0], [0.0, 1.2, 1.4]] LOdRTFfn [0.0, 1.2]
1 [[1.0, 0.0, 2.0], [0.0, 1.4, 1.4]] Lckq4LkU [0.0]
2 [[2.0, 0.0, 1.0], [0.0, 1.1, 1.4]] LcsYHodm [0.0, 1.1]
la
0 [LOdRTFfn, Lckq4LkU]
1 [Lckq4LkU]
2 [LcsYHodm, LOdRTFfn]

Python: how to add first value in each list

A Posn is a list of length two [x,y], where
x and y are both Float values, corresponding to
the x and y coordinates of the point, respectively.
make_posn: float float -> Posn
def make_posn(x_coord, y_coord):
return [x_coord, y_coord]
How do I add all the x-values in a list of Posns?
Ex: [ [3.0, 4.0], [8.0, -1.0], [0.0, 2.0]] would be 11
sum them:
In [2]: sum(x[0] for x in [ [3.0, 4.0], [8.0, -1.0], [0.0, 2.0]])
Out[2]: 11.0
The following piece of code should work for your
_sum = 0.0
for sublist in [ [3.0, 4.0], [8.0, -1.0], [0.0, 2.0]]:
_sum += sublist[0]
It initializes a sum accumulator to zero and then iterates over the sublist elements of the list to add the value of the first element of each list, to the initial sum

Categories

Resources