  # numpy.allclose () in Python

allclose | Arrays | NumPy | Python Methods and Functions

If the following equation is elementwise True, then allclose returns True.
` absolute (arr1 - arr2) & lt; = (atol + rtol * absolute (arr2)) `
Since the above equation is not symmetric in arr1 and arr2, in some rare cases allclose (arr1, arr2) may differ from allclose (arr2, arr1).

Syntax: numpy.allclose (arr1, arr2, rtol, atol, equal_nan = False)

Parameters:
arr1: [array_like] Input 1st array.
arr2: [array_like] Input 2nd array.
rtol: [float] The relative tolerance parameter.
atol: [float] The absolute tolerance parameter.
equal_nan: [bool] Whether to compare NaN`s as equal. If True, NaN`s in arr1 will be considered equal to NaN`s in arr2 in the output array.

Return: [bool] Returns True if the two arrays are equal within the given tolerance , otherwise it returns False.

Code # 1:

` `

 ` # Python program, explaining ` ` # allclose () function `   ` import ` ` numpy as geek ` `   # input arrays `` in_arr1 = geek.array ([ 5e5 , 1e - 7 , 4.000004e6 ]) print ( "1st Input array:" , in_arr1)    in_arr2 = geek.array ([ 5.00001e5 , 1e - 7 , 4e6 ]) print ( "2nd Input array:" , in_arr2)    # setting absolute and relative tolerance rtol =   1e - 05 atol = 1e - 08   res = geek.allclose (in_arr1, in_arr2, rtol, atol) print ( " Are the two arrays are equal within the tolerance: " , res) `

` ` Exit:

` 1st Input array: [5.00000000e + 05 1.00000000e-07 4.00000400e + 06] 2nd Input array: [5.00001000e + 05 1.00000000e-07 4.00000000e + 06] Are the two arrays are equal within the tolerance: True `

Code # 2:

` # Python program explaining `
` # allclose () function `

` import ` ` numpy as geek `

` # input arrays `

` in_arr1 ` ` = ` ` geek.array ([` ` 5e5 ` `, ` ` 1e ` ` - ` ` 7 ` `, ` ` 4.000004e6 ` `]) `

` print ` ` (` ` "1st Input array:" ` `, in_arr1) `

` in_arr2 ` ` = ` < code class = "plain"> geek.array ([ ` 5.00001e5 ` `, ` ` 1e ` ` - ` ` 7 ` `, ` ` 4e6 ` `]) `

` print ` ` (` ` "2nd Input array:" ` `, in_arr2) `

` `
` # setting absolute and relative tolerance `

` rtol ` ` = ` ` 1e ` ` - ` ` 06 `

` atol ` ` = ` ` 1e ` ` - ` ` 09 `

` res ` ` = ` ` geek.allclose (in_arr1, in_arr2, rtol, atol) `

` print ` ` (` `" Are the two arrays are equal within the tolerance: "` `, res) `

Exit:

` 1st Input array: [5000000.0, 1e-07, 40000004.0] 2nd Input array: [5000001.0, 1e-07, 40000000.0] Are the two arrays are equal within the tolerance: True `

Code # 3:

 ` # Python program explaining ` ` # allclose () function `   ` import ` ` numpy as geek `   ` # input arrays ` ` i n_arr1 ` ` = ` ` geek.array ([` ` 5e5 ` `, ` ` 1e ` ` - ` ` 7 ` `, geek.nan]) ` ` print ` ` ( "1st Input array:" , in_arr1) ``   in_arr2 = geek.array ([ 5e5 , 1e - 7 , geek.nan]) print ( " 2nd Input array: " , in_arr2)    # setting absolute and relative tolerance rtol = 1e - 06 atol = 1e - 09    res = geek.allclose (in_arr1, in_arr2, rtol, atol) print ( "Are the two arrays are equal within the tolerance:" , res) `

Exit:

` 1st Input array: [500000.0, 1e-07, nan] 2nd Input array: [500000.0, 1e-07, nan] Are the two arrays are equal within the tolerance: False `

Code # 4:

` `

` # Python program explaining # allclose () function   import numpy as geek   # input arrays in_arr1 = geek.array ([ 5e5 , 1e - 7 , geek.nan]) print ( "1st Input array:" , in_arr1)    in_arr2 = geek.array ([ 5e5 , 1e - 7 , geek.nan]) print ( " 2nd Input array: " , in_arr2)     # setting absolute and relative tolerance rtol = 1e - 06 atol = 1e - 09   res = geek.all close (in_arr1, in_arr2, rtol, atol,  equal_nan = True )   print ( " Are the two arrays are equal within the tolerance: " , res) `

` ` Output :

` 1st Input array: [500000.0, 1e-07, nan] 2nd Input array: [500000.0, 1e-07, nan] Are the two arrays are equal within the tolerance: True `

## numpy.allclose () in Python: StackOverflow Questions

Update: The example below shows the old `pandas.rolling_mean` function which has been removed in recent versions of pandas. A modern equivalent of the function call below would be

``````In : pd.Series(x).rolling(window=N).mean().iloc[N-1:].values
Out:
array([ 0.49815397,  0.49844183,  0.49840518, ...,  0.49488191,
0.49456679,  0.49427121])
``````

pandas is more suitable for this than NumPy or SciPy. Its function rolling_mean does the job conveniently. It also returns a NumPy array when the input is an array.

It is difficult to beat `rolling_mean` in performance with any custom pure Python implementation. Here is an example performance against two of the proposed solutions:

``````In : import numpy as np

In : import pandas as pd

In : def running_mean(x, N):
...:     cumsum = np.cumsum(np.insert(x, 0, 0))
...:     return (cumsum[N:] - cumsum[:-N]) / N
...:

In : x = np.random.random(100000)

In : N = 1000

In : %timeit np.convolve(x, np.ones((N,))/N, mode="valid")
10 loops, best of 3: 172 ms per loop

In : %timeit running_mean(x, N)
100 loops, best of 3: 6.72 ms per loop

In : %timeit pd.rolling_mean(x, N)[N-1:]
100 loops, best of 3: 4.74 ms per loop

In : np.allclose(pd.rolling_mean(x, N)[N-1:], running_mean(x, N))
Out: True
``````

There are also nice options as to how to deal with the edge values.

Grasping the idea of `numpy.einsum()` is very easy if you understand it intuitively. As an example, let"s start with a simple description involving matrix multiplication.

To use `numpy.einsum()`, all you have to do is to pass the so-called subscripts string as an argument, followed by your input arrays.

Let"s say you have two 2D arrays, `A` and `B`, and you want to do matrix multiplication. So, you do:

``````np.einsum("ij, jk -> ik", A, B)
``````

Here the subscript string `ij` corresponds to array `A` while the subscript string `jk` corresponds to array `B`. Also, the most important thing to note here is that the number of characters in each subscript string must match the dimensions of the array. (i.e. two chars for 2D arrays, three chars for 3D arrays, and so on.) And if you repeat the chars between subscript strings (`j` in our case), then that means you want the `ein`sum to happen along those dimensions. Thus, they will be sum-reduced. (i.e. that dimension will be gone)

The subscript string after this `->`, will be our resultant array. If you leave it empty, then everything will be summed and a scalar value is returned as result. Else the resultant array will have dimensions according to the subscript string. In our example, it"ll be `ik`. This is intuitive because we know that for matrix multiplication the number of columns in array `A` has to match the number of rows in array `B` which is what is happening here (i.e. we encode this knowledge by repeating the char `j` in the subscript string)

Here are some more examples illustrating the use/power of `np.einsum()` in implementing some common tensor or nd-array operations, succinctly.

Inputs

``````# a vector
In : vec
Out: array([0, 1, 2, 3])

# an array
In : A
Out:
array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])

# another array
In : B
Out:
array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
``````

1) Matrix multiplication (similar to `np.matmul(arr1, arr2)`)

``````In : np.einsum("ij, jk -> ik", A, B)
Out:
array([[130, 130, 130, 130],
[230, 230, 230, 230],
[330, 330, 330, 330],
[430, 430, 430, 430]])
``````

2) Extract elements along the main-diagonal (similar to `np.diag(arr)`)

``````In : np.einsum("ii -> i", A)
Out: array([11, 22, 33, 44])
``````

3) Hadamard product (i.e. element-wise product of two arrays) (similar to `arr1 * arr2`)

``````In : np.einsum("ij, ij -> ij", A, B)
Out:
array([[ 11,  12,  13,  14],
[ 42,  44,  46,  48],
[ 93,  96,  99, 102],
[164, 168, 172, 176]])
``````

4) Element-wise squaring (similar to `np.square(arr)` or `arr ** 2`)

``````In : np.einsum("ij, ij -> ij", B, B)
Out:
array([[ 1,  1,  1,  1],
[ 4,  4,  4,  4],
[ 9,  9,  9,  9],
[16, 16, 16, 16]])
``````

5) Trace (i.e. sum of main-diagonal elements) (similar to `np.trace(arr)`)

``````In : np.einsum("ii -> ", A)
Out: 110
``````

6) Matrix transpose (similar to `np.transpose(arr)`)

``````In : np.einsum("ij -> ji", A)
Out:
array([[11, 21, 31, 41],
[12, 22, 32, 42],
[13, 23, 33, 43],
[14, 24, 34, 44]])
``````

7) Outer Product (of vectors) (similar to `np.outer(vec1, vec2)`)

``````In : np.einsum("i, j -> ij", vec, vec)
Out:
array([[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6],
[0, 3, 6, 9]])
``````

8) Inner Product (of vectors) (similar to `np.inner(vec1, vec2)`)

``````In : np.einsum("i, i -> ", vec, vec)
Out: 14
``````

9) Sum along axis 0 (similar to `np.sum(arr, axis=0)`)

``````In : np.einsum("ij -> j", B)
Out: array([10, 10, 10, 10])
``````

10) Sum along axis 1 (similar to `np.sum(arr, axis=1)`)

``````In : np.einsum("ij -> i", B)
Out: array([ 4,  8, 12, 16])
``````

11) Batch Matrix Multiplication

``````In : BM = np.stack((A, B), axis=0)

In : BM
Out:
array([[[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]],

[[ 1,  1,  1,  1],
[ 2,  2,  2,  2],
[ 3,  3,  3,  3],
[ 4,  4,  4,  4]]])

In : BM.shape
Out: (2, 4, 4)

# batch matrix multiply using einsum
In : BMM = np.einsum("bij, bjk -> bik", BM, BM)

In : BMM
Out:
array([[[1350, 1400, 1450, 1500],
[2390, 2480, 2570, 2660],
[3430, 3560, 3690, 3820],
[4470, 4640, 4810, 4980]],

[[  10,   10,   10,   10],
[  20,   20,   20,   20],
[  30,   30,   30,   30],
[  40,   40,   40,   40]]])

In : BMM.shape
Out: (2, 4, 4)
``````

12) Sum along axis 2 (similar to `np.sum(arr, axis=2)`)

``````In : np.einsum("ijk -> ij", BM)
Out:
array([[ 50,  90, 130, 170],
[  4,   8,  12,  16]])
``````

13) Sum all the elements in array (similar to `np.sum(arr)`)

``````In : np.einsum("ijk -> ", BM)
Out: 480
``````

14) Sum over multiple axes (i.e. marginalization)
(similar to `np.sum(arr, axis=(axis0, axis1, axis2, axis3, axis4, axis6, axis7))`)

``````# 8D array
In : R = np.random.standard_normal((3,5,4,6,8,2,7,9))

# marginalize out axis 5 (i.e. "n" here)
In : esum = np.einsum("ijklmnop -> n", R)

# marginalize out axis 5 (i.e. sum over rest of the axes)
In : nsum = np.sum(R, axis=(0,1,2,3,4,6,7))

In : np.allclose(esum, nsum)
Out: True
``````

15) Double Dot Products (similar to np.sum(hadamard-product) cf. 3)

``````In : A
Out:
array([[1, 2, 3],
[4, 2, 2],
[2, 3, 4]])

In : B
Out:
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])

In : np.einsum("ij, ij -> ", A, B)
Out: 124
``````

16) 2D and 3D array multiplication

Such a multiplication could be very useful when solving linear system of equations (Ax = b) where you want to verify the result.

``````# inputs
In : A = np.random.rand(3,3)
In : b = np.random.rand(3, 4, 5)

# solve for x
In : x = np.linalg.solve(A, b.reshape(b.shape, -1)).reshape(b.shape)

# 2D and 3D array multiplication :)
In : Ax = np.einsum("ij, jkl", A, x)

# indeed the same!
In : np.allclose(Ax, b)
Out: True
``````

On the contrary, if one has to use `np.matmul()` for this verification, we have to do couple of `reshape` operations to achieve the same result like:

``````# reshape 3D array `x` to 2D, perform matmul
# then reshape the resultant array to 3D
In : Ax_matmul = np.matmul(A, x.reshape(x.shape, -1)).reshape(x.shape)

# indeed correct!
In : np.allclose(Ax, Ax_matmul)
Out: True
``````

Bonus: Read more math here : Einstein-Summation and definitely here: Tensor-Notation

``````(A==B).all()
``````

test if all values of array (A==B) are True.

Note: maybe you also want to test A and B shape, such as `A.shape == B.shape`

Special cases and alternatives (from dbaupp"s answer and yoavram"s comment)

It should be noted that:

• this solution can have a strange behavior in a particular case: if either `A` or `B` is empty and the other one contains a single element, then it return `True`. For some reason, the comparison `A==B` returns an empty array, for which the `all` operator returns `True`.
• Another risk is if `A` and `B` don"t have the same shape and aren"t broadcastable, then this approach will raise an error.

In conclusion, if you have a doubt about `A` and `B` shape or simply want to be safe: use one of the specialized functions:

``````np.array_equal(A,B)  # test if same shape, same elements values
np.array_equiv(A,B)  # test if broadcastable shape, same elements values
np.allclose(A,B,...) # test if same shape, elements have close enough values
``````

The way to "start" the array that you want is:

``````arr = np.empty((0,3), int)
``````

Which is an empty array but it has the proper dimensionality.

``````>>> arr
array([], shape=(0, 3), dtype=int64)
``````

Then be sure to append along axis 0:

``````arr = np.append(arr, np.array([[1,2,3]]), axis=0)
arr = np.append(arr, np.array([[4,5,6]]), axis=0)
``````

But, @jonrsharpe is right. In fact, if you"re going to be appending in a loop, it would be much faster to append to a list as in your first example, then convert to a numpy array at the end, since you"re really not using numpy as intended during the loop:

``````In : %%timeit
.....: l = []
.....: for i in xrange(1000):
.....:     l.append([3*i+1,3*i+2,3*i+3])
.....: l = np.asarray(l)
.....:
1000 loops, best of 3: 1.18 ms per loop

In : %%timeit
.....: a = np.empty((0,3), int)
.....: for i in xrange(1000):
.....:     a = np.append(a, 3*i+np.array([[1,2,3]]), 0)
.....:
100 loops, best of 3: 18.5 ms per loop

In : np.allclose(a, l)
Out: True
``````

The numpythonic way to do it depends on your application, but it would be more like:

``````In : timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 ¬µs per loop

In : np.allclose(a, n)
Out: True
``````

## Efficient solution

Convolution is much better than straightforward approach, but (I guess) it uses FFT and thus quite slow. However specially for computing the running mean the following approach works fine

``````def running_mean(x, N):
cumsum = numpy.cumsum(numpy.insert(x, 0, 0))
return (cumsum[N:] - cumsum[:-N]) / float(N)
``````

The code to check

``````In: x = numpy.random.random(100000)
In: N = 1000
In: %timeit result1 = numpy.convolve(x, numpy.ones((N,))/N, mode="valid")
10 loops, best of 3: 41.4 ms per loop
In: %timeit result2 = running_mean(x, N)
1000 loops, best of 3: 1.04 ms per loop
``````

Note that `numpy.allclose(result1, result2)` is `True`, two methods are equivalent. The greater N, the greater difference in time.

### warning: although cumsum is faster there will be increased floating point error that may cause your results to be invalid/incorrect/unacceptable

``````# demonstrate loss of precision with only 100,000 points
np.random.seed(42)
x = np.random.randn(100000)+1e6
y1 = running_mean_convolve(x, 10)
y2 = running_mean_cumsum(x, 10)
assert np.allclose(y1, y2, rtol=1e-12, atol=0)
``````
• the more points you accumulate over the greater the floating point error (so 1e5 points is noticable, 1e6 points is more significant, more than 1e6 and you may want to resetting the accumulators)
• you can cheat by using `np.longdouble` but your floating point error still will get significant for relatively large number of points (around >1e5 but depends on your data)
• you can plot the error and see it increasing relatively fast
• the convolve solution is slower but does not have this floating point loss of precision
• the uniform_filter1d solution is faster than this cumsum solution AND does not have this floating point loss of precision