# Why np.nanmean() seems to be faster than np.mean()

**URL:** https://numba.discourse.group/t/why-np-nanmean-seems-to-be-faster-than-np-mean/2505
**Category:** Numba
**Created:** [April 10, 2024, 12:48am UTC](https://numba.discourse.group/t/why-np-nanmean-seems-to-be-faster-than-np-mean/2505 "2024-04-10T00:48:50Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![aeyou](https://yyz2.discourse-cdn.com/free1/user_avatar/numba.discourse.group/aeyou/32/1041_2.png) [@aeyou](https://numba.discourse.group/u/aeyou)
#### Post date: [April 10, 2024, 12:48am UTC](https://numba.discourse.group/t/why-np-nanmean-seems-to-be-faster-than-np-mean/2505/1 "2024-04-10T00:48:50Z")

</div>

I compared the following two function:

> @njit  
> def just\_mean(arr):  
> return np.mean(arr)

and

> @njit  
> def nan\_mean(arr):  
> return np.nanmean(arr)

on

> arr = np.array(random.sample(range(1, 100000), 5000))

the

> just\_mean()  
> function: 3.36 µs ± 613 ns per loop (mean ± std. dev. of 30 runs, 100,000 loops each)

the

> nan\_mean()  
> function: 3.28 µs ± 175 ns per loop (mean ± std. dev. of 30 runs, 100,000 loops each)

Just curious. Many thanks.

---

<div class="post-metadata">

### Author: ![Oyibo](https://avatars.discourse-cdn.com/v4/letter/o/4af34b/32.png) [@Oyibo](https://numba.discourse.group/u/Oyibo)
#### Post date: [April 10, 2024, 2:43am UTC](https://numba.discourse.group/t/why-np-nanmean-seems-to-be-faster-than-np-mean/2505/2 "2024-04-10T02:43:30Z")

</div>

Hey @aeyou ,

I wouldn’t say nanmean is faster than mean. It has similar performance.  
If the compiler is able to parallelize loops than isnan checks become cheap.  
This is the case if your array has a contiguous memory layout.

```auto
import numpy as np
from numba import njit

@njit
def just_mean(arr):
    return np.mean(arr)

@njit
def nan_mean(arr):
    return np.nanmean(arr)

# warmup
arr = np.arange(5.)
just_mean(arr)
nan_mean(arr)

N = 1_000_000

# time contiguous
arr = np.random.rand(N)
%timeit just_mean(arr)
%timeit nan_mean(arr)
# 1.12 ms ± 28.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
# 1.12 ms ± 8.41 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

# time strided
arr = np.random.rand(N*16)[::16]
%timeit just_mean(arr)
%timeit nan_mean(arr)
# 6.18 ms ± 32.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 7.29 ms ± 52.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

```

Contiguous memory layout:  
 ![Figure 2024-04-10 044005](https://global.discourse-cdn.com/free1/uploads/numba/original/2X/0/017d2b56af964387e2ce33930bbc3a3f9c447715.png)

Strided memory layout  
 ![Figure 2024-04-10 044022](https://global.discourse-cdn.com/free1/uploads/numba/original/2X/1/1cd79f238fd5ff2e94e7edbe9b63c00ea6c0b15f.png)
