How to select list elements based on crteria from other lists

Viewed 80

I am new to Python, coming from SciLab (an open source MatLab ersatz), which I am using as a toolbox for my analyses (test data analysis, reliability, acoustics, ...); I am definitely not a computer science lad. I have data in the form of lists of same length (vectors of same size in SciLab). I use some of them as parameter in order to select data from another one; e.g.

t_v = [1:10]; // a parameter vector  
p_v = [20:29]; another parameter vector 
res_v(t_v > 5 & p_v < 28); // are the res_v vector elements of which "corresponding" p_v and t_v values comply with my criteria; i can use it for analyses. 

This is very direct and simple in SciLab; I did not find the way to achieve the same with Python, either "Pythonically" or simply translated. Any idea that could help me, please? Have a nice day, Patrick.

3 Answers

Here's my modified solution according to your last comment.

t_v = list(range(1,10))
p_v = list(range(20,29))
res_v = list(range(30,39))

def first_idex_greater_than(search_number, lst): 
    for count, number in enumerate(lst):
        if number > search_number: 
            return count
        
def first_idex_lower_than(search_number, lst): 
    for count, number in enumerate(lst[::-1]):
        if number < search_number: 
            return len(lst) - count # since I searched lst from top to bottom, 
                                    # I need to also reverse count


t_v_index = first_idex_greater_than(5, t_v)
p_v_index = first_idex_lower_than(28, p_v)


print(res_v[min(t_v_index, p_v_index):max(t_v_index, p_v_index)])

It returns an array [35, 36, 37]. I'm sure you can optimize it better according to your needs.

The problem statement is not clearly defined, but this is what I interpret to be a likely solution.

import pandas as pd

tv = list(range(1, 11))
pv = list(range(20, 30))
res = list(range(30, 40))

df = pd.DataFrame({'tv': tv, 'pv': pv, 'res': res})

print(df)

def criteria(row, col1, a, col2, b):
    if (row[col1] > a) & (row[col2] < b):
        return True
    else:
        return False

df['select'] = df.apply(lambda row: criteria(row, 'tv', 5, 'pv', 28), axis=1)

selected_res = df.loc[df['select']]['res'].tolist()

print(selected_res)

# ... or another way ..
print(df.loc[(df.tv > 5) & (df.pv < 28)]['res'])

This produces a dataframe where each column is the original lists, and applies a selection criteria, based on columns tv and pv to identify the rows in which the criteria, applied dependently to the 2 lists, is satisfied (or not), and then creates a new column of booleans identifying the rows where the criteria is either True or False.

[35, 36, 37]

5    35
6    36
7    37

You could use numpy arrays. It's easy:

import numpy as np                                                                                                                                                                            
                                                                                                                                                                                              
par1 = np.array([1,1,5,5,5,1,1])                                                                                                                                                              
par2 = np.array([-1,1,1,-1,1,1,1])                                                                                                                                                            
data = np.array([1,2,3,4,5,6,7])                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                            
print(par1)                                                                                                                                                                                   
print(par2)                                                                                                                                                                                   
print(data)  
                                                                                                                                                                         
bool_filter = (par1[:]>1) & (par2[:]<0)
# example to do it directly in the array                                                                                                                                                                                    
filtered_data = data[ par1[:]>1 ]                                                                                                                                                             
print( filtered_data )                                                                                                                                                                        
#filtering with the two parameters                                                                                                                                                                                              
filtered_data_twice = data[ bool_filter==True ]                                                                                                                                                       
print( filtered_data_twice )  

output:

[1 1 5 5 5 1 1]
[-1  1  1 -1  1  1  1]
[1 2 3 4 5 6 7]
[3 4 5]
[4]
                               

Note that it does not keep the same number of elements.

Related