Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to subset list elements that lie between two missing values?

With a list containing some missing values such as this:

[10, 11, 12,np.nan, 14, np.nan, 16, 17, np.nan, 19, np.nan]

How can you subset the values that are positioned between two missing (nan) values?

I know how to do it with a for loop :

# imports
import numpy as np

# input
lst=[10,11,12,np.nan, 14, np.nan, 16, 17, np.nan, 19, np.nan]

# define an empty list and build on that in a For Loop
subset=[]
for i, elem in enumerate(lst):
    if np.isnan(lst[i-1]) and np.isnan(lst[i+1]):
        subset.extend([elem])

print(subset)

# output
# [14, 19]

Any suggestions on how to do this in a less cumbersome way?

like image 680
vestland Avatar asked Mar 06 '20 12:03

vestland


People also ask

How do you find the missing values between two lists in Python?

Step 1 : first we create two user input list. A & B Step 2 : Insert A and B to a set. Step 3 : for finding the missing values of first list we apply difference function, difference of B from A. Step 4 : for finding the Additional values of first list we apply difference function, difference of A from B.


3 Answers

you can use the built-in function zip:

subset = [e2 for e1, e2, e3 in zip(lst, lst[1:], lst[2:]) if np.isnan(e1) and not np.isnan(e2) and np.isnan(e3)]
print(subset)

output:

[14, 19]
like image 107
kederrac Avatar answered Nov 15 '22 21:11

kederrac


I'm a NumPy noob, so probably can be done better...

>>> a = np.array(lst)
>>> a[1:-1][np.isnan(a[:-2]) & np.isnan(a[2:])]
array([14., 19.])

For my examples [1, np.nan] and [np.nan] in the comments, this produces an empty array as intended.

Or as Georgy commented, do isnan only once:

>>> a = np.array(lst)
>>> nan = np.isnan(a)
>>> a[1:-1][nan[:-2] & nan[2:]]
array([14., 19.])

As kaya3 commented, if there can be three nans in a row, these solutions would include the middle one in the result (like your original does). Here's one that doesn't (for the test I replaced the 14 with a nan):

>>> a[1:-1][nan[:-2] & ~nan[1:-1] & nan[2:]]
array([19.])
like image 34
Kelly Bundy Avatar answered Nov 15 '22 21:11

Kelly Bundy


Use list comprehension

import numpy as np
lst=[10,11,12,np.nan, 14, np.nan, 16, 17, np.nan, np.nan, np.nan]
subset = [elem for i, elem in enumerate(lst) if i and i < len(lst)-1 and np.isnan(lst[i-1]) and np.isnan(lst[i+1]) and not np.isnan(elem)]
print(subset)

Corrected the mistakes that were pointed out by other contributors. This should work for all the cases now.

like image 25
Eternal Avatar answered Nov 15 '22 20:11

Eternal