Bottleneck provides the following functions:
reduce  nansum, nanmean, nanstd, nanvar, nanmin, nanmax, median, nanmedian, ss, nanargmin, nanargmax, anynan, allnan 
nonreduce  replace 
nonreduce with axis  rankdata, nanrankdata, partsort, argpartsort, push 
moving window  move_sum, move_mean, move_std, move_min, move_min, move_max, move_argmin, move_argmax, move_median, move_rank 
Functions the reduce the input array along the specified axis.
Sum of array elements along given axis treating NaNs as zero.
The data type (dtype) of the output is the same as the input. On 64bit operating systems, 32bit input is NOT upcast to 64bit accumulator and return values.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

Notes
No error is raised on overflow.
If positive or negative infinity are present the result is positive or negative infinity. But if both positive and negative infinity are present, the result is Not A Number (NaN).
Examples
>>> bn.nansum(1)
1
>>> bn.nansum([1])
1
>>> bn.nansum([1, np.nan])
1.0
>>> a = np.array([[1, 1], [1, np.nan]])
>>> bn.nansum(a)
3.0
>>> bn.nansum(a, axis=0)
array([ 2., 1.])
When positive infinity and negative infinity are present:
>>> bn.nansum([1, np.nan, np.inf])
inf
>>> bn.nansum([1, np.nan, np.NINF])
inf
>>> bn.nansum([1, np.nan, np.inf, np.NINF])
nan
Mean of array elements along given axis ignoring NaNs.
float64 intermediate and return values are used for integer inputs.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Notes
No error is raised on overflow. (The sum is computed and then the result is divided by the number of nonNaN elements.)
If positive or negative infinity are present the result is positive or negative infinity. But if both positive and negative infinity are present, the result is Not A Number (NaN).
Examples
>>> bn.nanmean(1)
1.0
>>> bn.nanmean([1])
1.0
>>> bn.nanmean([1, np.nan])
1.0
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.nanmean(a)
2.0
>>> bn.nanmean(a, axis=0)
array([ 1., 4.])
When positive infinity and negative infinity are present:
>>> bn.nanmean([1, np.nan, np.inf])
inf
>>> bn.nanmean([1, np.nan, np.NINF])
inf
>>> bn.nanmean([1, np.nan, np.inf, np.NINF])
nan
Standard deviation along the specified axis, ignoring NaNs.
float64 intermediate and return values are used for integer inputs.
Instead of a faster onepass algorithm, a more stable twopass algorithm is used.
An example of a onepass algorithm:
>>> np.sqrt((arr*arr).mean()  arr.mean()**2)
An example of a twopass algorithm:
>>> np.sqrt(((arr  arr.mean())**2).mean())
Note in the twopass algorithm the mean must be found (first pass) before the squared deviation (second pass) can be found.
Parameters:  arr : array_like
axis : {int, None}, optional
ddof : int, optional


Returns:  y : ndarray

See also
Notes
If positive or negative infinity are present the result is Not A Number (NaN).
Examples
>>> bn.nanstd(1)
0.0
>>> bn.nanstd([1])
0.0
>>> bn.nanstd([1, np.nan])
0.0
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.nanstd(a)
1.4142135623730951
>>> bn.nanstd(a, axis=0)
array([ 0., 0.])
When positive infinity or negative infinity are present NaN is returned:
>>> bn.nanstd([1, np.nan, np.inf])
nan
Variance along the specified axis, ignoring NaNs.
float64 intermediate and return values are used for integer inputs.
Instead of a faster onepass algorithm, a more stable twopass algorithm is used.
An example of a onepass algorithm:
>>> (arr*arr).mean()  arr.mean()**2
An example of a twopass algorithm:
>>> ((arr  arr.mean())**2).mean()
Note in the twopass algorithm the mean must be found (first pass) before the squared deviation (second pass) can be found.
Parameters:  arr : array_like
axis : {int, None}, optional
ddof : int, optional


Returns:  y : ndarray

See also
Notes
If positive or negative infinity are present the result is Not A Number (NaN).
Examples
>>> bn.nanvar(1)
0.0
>>> bn.nanvar([1])
0.0
>>> bn.nanvar([1, np.nan])
0.0
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.nanvar(a)
2.0
>>> bn.nanvar(a, axis=0)
array([ 0., 0.])
When positive infinity or negative infinity are present NaN is returned:
>>> bn.nanvar([1, np.nan, np.inf])
nan
Minimum values along specified axis, ignoring NaNs.
When allNaN slices are encountered, NaN is returned for that slice.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> bn.nanmin(1)
1
>>> bn.nanmin([1])
1
>>> bn.nanmin([1, np.nan])
1.0
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.nanmin(a)
1.0
>>> bn.nanmin(a, axis=0)
array([ 1., 4.])
Maximum values along specified axis, ignoring NaNs.
When allNaN slices are encountered, NaN is returned for that slice.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> bn.nanmax(1)
1
>>> bn.nanmax([1])
1
>>> bn.nanmax([1, np.nan])
1.0
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.nanmax(a)
4.0
>>> bn.nanmax(a, axis=0)
array([ 1., 4.])
Median of array elements along given axis.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> a = np.array([[10, 7, 4], [3, 2, 1]])
>>> bn.median(a)
3.5
>>> bn.median(a, axis=0)
array([ 6.5, 4.5, 2.5])
>>> bn.median(a, axis=1)
array([ 7., 2.])
Median of array elements along given axis ignoring NaNs.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> a = np.array([[np.nan, 7, 4], [3, 2, 1]])
>>> a
array([[ nan, 7., 4.],
[ 3., 2., 1.]])
>>> bn.nanmedian(a)
3.0
>> bn.nanmedian(a, axis=0)
array([ 3. , 4.5, 2.5])
>> bn.nanmedian(a, axis=1)
array([ 5.5, 2. ])
Sum of the square of each element along the specified axis.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

Examples
>>> a = np.array([1., 2., 5.])
>>> bn.ss(a)
30.0
And calculating along an axis:
>>> b = np.array([[1., 2., 5.], [2., 5., 6.]])
>>> bn.ss(b, axis=1)
array([ 30., 65.])
Indices of the minimum values along an axis, ignoring NaNs.
For allNaN slices ValueError is raised. Unlike NumPy, the results can be trusted if a slice contains only NaNs and Infs.
Parameters:  a : array_like
axis : {int, None}, optional


Returns:  index_array : ndarray

See also
Examples
>>> a = np.array([[np.nan, 4], [2, 3]])
>>> bn.nanargmin(a)
2
>>> a.flat[1]
2.0
>>> bn.nanargmax(a, axis=0)
array([1, 1])
>>> bn.nanargmax(a, axis=1)
array([1, 0])
Indices of the maximum values along an axis, ignoring NaNs.
For allNaN slices ValueError is raised. Unlike NumPy, the results can be trusted if a slice contains only NaNs and Infs.
Parameters:  a : array_like
axis : {int, None}, optional


Returns:  index_array : ndarray

See also
Examples
>>> a = np.array([[np.nan, 4], [2, 3]])
>>> bn.nanargmax(a)
1
>>> a.flat[1]
4.0
>>> bn.nanargmax(a, axis=0)
array([1, 0])
>>> bn.nanargmax(a, axis=1)
array([1, 1])
Test whether any array element along a given axis is NaN.
Returns the same output as np.isnan(arr).any(axis)
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : bool or ndarray

See also
Examples
>>> bn.anynan(1)
False
>>> bn.anynan(np.nan)
True
>>> bn.anynan([1, np.nan])
True
>>> a = np.array([[1, 4], [1, np.nan]])
>>> bn.anynan(a)
True
>>> bn.anynan(a, axis=0)
array([False, True], dtype=bool)
Test whether all array elements along a given axis are NaN.
Returns the same output as np.isnan(arr).all(axis)
Note that allnan([]) is True to match np.isnan([]).all() and all([])
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : bool or ndarray

See also
Examples
>>> bn.allnan(1)
False
>>> bn.allnan(np.nan)
True
>>> bn.allnan([1, np.nan])
False
>>> a = np.array([[1, np.nan], [1, np.nan]])
>>> bn.allnan(a)
False
>>> bn.allnan(a, axis=0)
array([False, True], dtype=bool)
An empty array returns True:
>>> bn.allnan([])
True
which is similar to:
>>> all([])
True
>>> np.isnan([]).all()
True
Functions that do not reduce the input array and do not take axis as input.
Replace (inplace) given scalar values of an array with new values.
The equivalent numpy function:
arr[arr==old] = new
Or in the case where old=np.nan:
arr[np.isnan(old)] = new
Parameters:  arr : numpy.ndarray
old : scalar
new : scalar


Returns:  None, the operation is inplace. : 
Examples
Replace zero with 3 (note that the input array is modified):
>>> a = np.array([1, 2, 0])
>>> bn.replace(a, 0, 3)
>>> a
array([1, 2, 3])
Replace np.nan with 0:
>>> a = np.array([1, 2, np.nan])
>>> bn.replace(a, np.nan, 0)
>>> a
array([ 1., 2., 0.])
Functions that do not reduce the input array but operate along a specified axis.
Ranks the data, dealing with ties appropriately.
Equal values are assigned a rank that is the average of the ranks that would have been otherwise assigned to all of the values within that set. Ranks begin at 1, not 0.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> bn.rankdata([0, 2, 2, 3])
array([ 1. , 2.5, 2.5, 4. ])
>>> bn.rankdata([[0, 2], [2, 3]])
array([ 1. , 2.5, 2.5, 4. ])
>>> bn.rankdata([[0, 2], [2, 3]], axis=0)
array([[ 1., 1.],
[ 2., 2.]])
>>> bn.rankdata([[0, 2], [2, 3]], axis=1)
array([[ 1., 2.],
[ 1., 2.]])
Ranks the data, dealing with ties and NaNs appropriately.
Equal values are assigned a rank that is the average of the ranks that would have been otherwise assigned to all of the values within that set. Ranks begin at 1, not 0.
NaNs in the input array are returned as NaNs.
Parameters:  arr : array_like
axis : {int, None}, optional


Returns:  y : ndarray

See also
Examples
>>> bn.nanrankdata([np.nan, 2, 2, 3])
array([ nan, 1.5, 1.5, 3. ])
>>> bn.nanrankdata([[np.nan, 2], [2, 3]])
array([ nan, 1.5, 1.5, 3. ])
>>> bn.nanrankdata([[np.nan, 2], [2, 3]], axis=0)
array([[ nan, 1.],
[ 1., 2.]])
>>> bn.nanrankdata([[np.nan, 2], [2, 3]], axis=1)
array([[ nan, 1.],
[ 1., 2.]])
Partial sorting of array elements along given axis.
A partially sorted array is one in which the n smallest values appear (in any order) in the first n elements. The remaining largest elements are also unordered. Due to the algorithm used (Wirth’s method), the nth smallest element is in its sorted position (at index n1).
Shuffling the input array may change the output. The only guarantee is that the first n elements will be the n smallest and the remaining element will appear in the remainder of the output.
This functions is not protected against NaN. Therefore, you may get unexpected results if the input contains NaN.
Parameters:  arr : array_like
n : int
axis : {int, None}, optional


Returns:  y : ndarray

See also
Notes
Unexpected results may occur if the input array contains NaN.
Examples
Create a numpy array:
>>> a = np.array([1, 0, 3, 4, 2])
Partially sort array so that the first 3 elements are the smallest 3 elements (note, as in this example, that the smallest 3 elements may not be sorted):
>>> bn.partsort(a, n=3)
array([1, 0, 2, 4, 3])
Now partially sort array so that the last 2 elements are the largest 2 elements:
>>> bn.partsort(a, n=a.shape[0]2)
array([1, 0, 2, 3, 4])
Return indices that would partially sort an array.
A partially sorted array is one in which the n smallest values appear (in any order) in the first n elements. The remaining largest elements are also unordered. Due to the algorithm used (Wirth’s method), the nth smallest element is in its sorted position (at index n1).
Shuffling the input array may change the output. The only guarantee is that the first n elements will be the n smallest and the remaining element will appear in the remainder of the output.
This functions is not protected against NaN. Therefore, you may get unexpected results if the input contains NaN.
Parameters:  arr : array_like
n : int
axis : {int, None}, optional


Returns:  y : ndarray

See also
Notes
Unexpected results may occur if the input array contains NaN.
Examples
Create a numpy array:
>>> a = np.array([1, 0, 3, 4, 2])
Find the indices that partially sort that array so that the first 3 elements are the smallest 3 elements:
>>> index = bn.argpartsort(a, n=3)
>>> index
array([0, 1, 4, 3, 2])
Let’s use the indices to partially sort the array (note, as in this example, that the smallest 3 elements may not be in order):
>>> a[index]
array([1, 0, 2, 4, 3])
Fill missing values (NaNs) with most recent nonmissing values.
Filling proceeds along the specified axis from small index values to large index values.
Parameters:  arr : array_like
n : float, optional
axis : int, optional


Returns:  y : ndarray

See also
Examples
>>> arr = np.array([5, np.nan, np.nan, 6, np.nan])
>>> bn.push(arr)
array([ 5., 5., 5., 6., 6.])
>>> bn.push(arr, n=1)
array([ 5., 5., nan, 6., 6.])
>>> bn.push(arr, n=2)
array([ 5., 5., 5., 6., 6.])
Functions that operate along a (1d) moving window.
Moving window sum along the specified axis, optionally ignoring NaNs.
This function cannot handle input arrays that contain Inf. When the window contains Inf, the output will correctly be Inf. However, when Inf moves out of the window, the remaining output values in the slice will incorrectly be NaN.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_sum(arr, window=2)
array([ nan, 3., 5., nan, nan])
>>> bn.move_sum(arr, window=2, min_count=1)
array([ 1., 3., 5., 3., 5.])
Moving window mean along the specified axis, optionally ignoring NaNs.
This function cannot handle input arrays that contain Inf. When the window contains Inf, the output will correctly be Inf. However, when Inf moves out of the window, the remaining output values in the slice will incorrectly be NaN.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_mean(arr, window=2)
array([ nan, 1.5, 2.5, nan, nan])
>>> bn.move_mean(arr, window=2, min_count=1)
array([ 1. , 1.5, 2.5, 3. , 5. ])
Moving window standard deviation along the specified axis, optionally ignoring NaNs.
This function cannot handle input arrays that contain Inf. When Inf enters the moving window, the outout becomes NaN and will continue to be NaN for the remainer of the slice.
Unlike bn.nanstd, which uses a twopass algorithm, move_nanstd uses a onepass algorithm called Welford’s method. The algorithm is slow but numerically stable for cases where the mean is large compared to the standard deviation.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional
ddof : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_std(arr, window=2)
array([ nan, 0.5, 0.5, nan, nan])
>>> bn.move_std(arr, window=2, min_count=1)
array([ 0. , 0.5, 0.5, 0. , 0. ])
Moving window variance along the specified axis, optionally ignoring NaNs.
This function cannot handle input arrays that contain Inf. When Inf enters the moving window, the outout becomes NaN and will continue to be NaN for the remainer of the slice.
Unlike bn.nanvar, which uses a twopass algorithm, move_nanvar uses a onepass algorithm called Welford’s method. The algorithm is slow but numerically stable for cases where the mean is large compared to the standard deviation.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional
ddof : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_var(arr, window=2)
array([ nan, 0.25, 0.25, nan, nan])
>>> bn.move_var(arr, window=2, min_count=1)
array([ 0. , 0.25, 0.25, 0. , 0. ])
Moving window minimum along the specified axis, optionally ignoring NaNs.
float64 output is returned for all input data types.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_min(arr, window=2)
array([ nan, 1., 2., nan, nan])
>>> bn.move_min(arr, window=2, min_count=1)
array([ 1., 1., 2., 3., 5.])
Moving window maximum along the specified axis, optionally ignoring NaNs.
float64 output is returned for all input data types.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, np.nan, 5.0])
>>> bn.move_max(arr, window=2)
array([ nan, 2., 3., nan, nan])
>>> bn.move_max(arr, window=2, min_count=1)
array([ 1., 2., 3., 3., 5.])
Moving window index of minimum along the specified axis, optionally ignoring NaNs.
Index 0 is at the rightmost edge of the window. For example, if the array is monotonically decreasing (increasing) along the specified axis then the output array will contain zeros (window1).
If there is a tie in input values within a window, then the rightmost index is returned.
float64 output is returned for all input data types.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
>>> bn.move_argmin(arr, window=2)
array([ nan, 1., 1., 1., 1.])
>>> arr = np.array([5.0, 4.0, 3.0, 2.0, 1.0])
>>> bn.move_argmin(arr, window=2)
array([ nan, 0., 0., 0., 0.])
>>> arr = np.array([2.0, 3.0, 4.0, 1.0, 7.0, 5.0, 6.0])
>>> bn.move_argmin(arr, window=3)
array([ nan, nan, 2., 0., 1., 2., 1.])
Moving window index of maximum along the specified axis, optionally ignoring NaNs.
Index 0 is at the rightmost edge of the window. For example, if the array is monotonically increasing (decreasing) along the specified axis then the output array will contain zeros (window1).
If there is a tie in input values within a window, then the rightmost index is returned.
float64 output is returned for all input data types.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
>>> bn.move_argmax(arr, window=2)
array([ nan, 0., 0., 0., 0.])
>>> arr = np.array([5.0, 4.0, 3.0, 2.0, 1.0])
>>> bn.move_argmax(arr, window=2)
array([ nan, 1., 1., 1., 1.])
>>> arr = np.array([2.0, 3.0, 4.0, 1.0, 7.0, 5.0, 6.0])
>>> bn.move_argmax(arr, window=3)
array([ nan, nan, 0., 1., 0., 1., 2.])
Moving window median along the specified axis, optionally ignoring NaNs.
float64 output is returned for all input data types.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
>>> arr = np.array([1.0, 2.0, 3.0, 4.0])
>>> bn.move_median(arr, window=2)
array([ nan, 1.5, 2.5, 3.5])
>>> bn.move_median(arr, window=2, min_count=1)
array([ 1. , 1.5, 2.5, 3.5])
Moving window ranking along the specified axis, optionally ignoring NaNs.
The output is normalized to be between 1 and 1. For example, with a window width of 3 (and with no ties), the possible output values are 1, 0, 1.
Ties are broken by averaging the rankings. See the examples below.
The runtime depends almost linearly on window. The more NaNs there are in the input array, the shorter the runtime.
Parameters:  arr : ndarray
window : int
min_count: {int, None}, optional :
axis : int, optional


Returns:  y : ndarray

Examples
With window=3 and no ties, there are 3 possible output values, i.e. [1., 0., 1.]:
>>> arr = np.array([1, 2, 3, 9, 8, 7, 5, 6, 4])
>>> bn.move_rank(arr, window=3)
array([ nan, nan, 1., 1., 0., 1., 1., 0., 1.])
Ties are broken by averaging the rankings of the tied elements:
>>> arr = np.array([1, 2, 3, 3, 3, 4])
>>> bn.move_rank(arr, window=3)
array([ nan, nan, 1. , 0.5, 0. , 1. ])
In an increasing sequence, the moving window ranking is always equal to 1:
>>> arr = np.array([1, 2, 3, 4, 5])
>>> bn.move_rank(arr, window=2)
array([ nan, 1., 1., 1., 1.])