1

I have a simple list that contains numbers and NaN values. Is there a way to take the AVG between two NaN values? an example could be like this:

list = [NaN, 5, 6, 7, NaN, NaN, NaN, 6, 2, 8, 5, 4, NaN, NaN]

and I would expect an output like

Output = [6,5] 
D_00
  • 1,440
  • 2
  • 13
  • 32
IMA
  • 23
  • 3

3 Answers3

4

Use the groupby from itertools -

import numpy as np
from itertools import groupby
NaN = np.nan
lst = [NaN, 5, 6, 7, NaN, NaN, NaN, 6, 2, 8, 5, 4, NaN, NaN]
[np.mean(list(g)) for k, g in groupby(lst, key=lambda x: x is not NaN) if k]
# [6.0, 5.0]
Mortz
  • 4,654
  • 1
  • 19
  • 35
1

A simple method requiring no additional skills:

import numpy as np

## NaN is assumed to be pre-defined by the users, e.g.: NaN = np.nan or NaN = float('nan')

def get_mean_between_nan(ar):
    out = list()
    t = list()
    for x in ar:
        if np.isnan(x):
            if len(t) > 0:
                out.append(np.mean(t))
                t = list()
        else:
            t.append(x)
    if len(t) > 0:
        out.append(np.mean(t))
    return out
biock
  • 93
  • 1
  • 6
0

Following on from https://stackoverflow.com/a/30825549/1021819, first split the list into a chunked list-of-lists:

NaN=None # or np.nan, float('nan'), 'nan' or any other separator value you like = even '/'
my_list = [NaN, 5, 6, 7, NaN, NaN, NaN, 6, 2, 8, 5, 4, NaN, NaN]

from itertools import groupby
chunks = list(list(g) for k,g in groupby(my_list, key=lambda x: x is not NaN) if k))
# [[5, 6, 7], [6, 2, 8, 5, 4]]

Then you can use the built-in statistics.mean() as follows:

import statistics
output = [statistics.mean(chunk) for chunk in chunks]
# [6, 5]

There you go.

Notes:

  1. No need for numpy. But if you do want a pure numpy solution you can use https://stackoverflow.com/a/31863171/1021819
  2. Don't use list for your variable name since it is the name of a built-in type!
jtlz2
  • 7,700
  • 9
  • 64
  • 114