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: **

` `

` ` |

` `

**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: **

` ` |

** 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

**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 [8]: pd.Series(x).rolling(window=N).mean().iloc[N-1:].values
Out[8]:
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 [1]: import numpy as np
In [2]: import pandas as pd
In [3]: def running_mean(x, N):
...: cumsum = np.cumsum(np.insert(x, 0, 0))
...: return (cumsum[N:] - cumsum[:-N]) / N
...:
In [4]: x = np.random.random(100000)
In [5]: N = 1000
In [6]: %timeit np.convolve(x, np.ones((N,))/N, mode="valid")
10 loops, best of 3: 172 ms per loop
In [7]: %timeit running_mean(x, N)
100 loops, best of 3: 6.72 ms per loop
In [8]: %timeit pd.rolling_mean(x, N)[N-1:]
100 loops, best of 3: 4.74 ms per loop
In [9]: np.allclose(pd.rolling_mean(x, N)[N-1:], running_mean(x, N))
Out[9]: 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

To use ** numpy.einsum()**, all you have to do is to pass the so-called

Let"s say you have two 2D arrays, ** A** and

`B`

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

Here the *subscript string* ** ij** corresponds to array

`A`

`jk`

`B`

`j`

`ein`

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

`ik`

`A`

`B`

`j`

Here are some more examples illustrating the use/power of ** np.einsum()** in implementing some common

**Inputs**

```
# a vector
In [197]: vec
Out[197]: array([0, 1, 2, 3])
# an array
In [198]: A
Out[198]:
array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])
# another array
In [199]: B
Out[199]:
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 [200]: np.einsum("ij, jk -> ik", A, B)
Out[200]:
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 [202]: np.einsum("ii -> i", A)
Out[202]: array([11, 22, 33, 44])
```

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

```
In [203]: np.einsum("ij, ij -> ij", A, B)
Out[203]:
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 [210]: np.einsum("ij, ij -> ij", B, B)
Out[210]:
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 [217]: np.einsum("ii -> ", A)
Out[217]: 110
```

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

```
In [221]: np.einsum("ij -> ji", A)
Out[221]:
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 [255]: np.einsum("i, j -> ij", vec, vec)
Out[255]:
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 [256]: np.einsum("i, i -> ", vec, vec)
Out[256]: 14
```

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

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

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

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

**11) Batch Matrix Multiplication**

```
In [287]: BM = np.stack((A, B), axis=0)
In [288]: BM
Out[288]:
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 [289]: BM.shape
Out[289]: (2, 4, 4)
# batch matrix multiply using einsum
In [292]: BMM = np.einsum("bij, bjk -> bik", BM, BM)
In [293]: BMM
Out[293]:
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 [294]: BMM.shape
Out[294]: (2, 4, 4)
```

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

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

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

```
In [335]: np.einsum("ijk -> ", BM)
Out[335]: 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 [354]: R = np.random.standard_normal((3,5,4,6,8,2,7,9))
# marginalize out axis 5 (i.e. "n" here)
In [363]: esum = np.einsum("ijklmnop -> n", R)
# marginalize out axis 5 (i.e. sum over rest of the axes)
In [364]: nsum = np.sum(R, axis=(0,1,2,3,4,6,7))
In [365]: np.allclose(esum, nsum)
Out[365]: True
```

**15) Double Dot Products** (similar to

```
In [772]: A
Out[772]:
array([[1, 2, 3],
[4, 2, 2],
[2, 3, 4]])
In [773]: B
Out[773]:
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
In [774]: np.einsum("ij, ij -> ", A, B)
Out[774]: 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 [115]: A = np.random.rand(3,3)
In [116]: b = np.random.rand(3, 4, 5)
# solve for x
In [117]: x = np.linalg.solve(A, b.reshape(b.shape[0], -1)).reshape(b.shape)
# 2D and 3D array multiplication :)
In [118]: Ax = np.einsum("ij, jkl", A, x)
# indeed the same!
In [119]: np.allclose(Ax, b)
Out[119]: 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 [123]: Ax_matmul = np.matmul(A, x.reshape(x.shape[0], -1)).reshape(x.shape)
# indeed correct!
In [124]: np.allclose(Ax, Ax_matmul)
Out[124]: 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 [210]: %%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 [211]: %%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 [214]: np.allclose(a, l)
Out[214]: True
```

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

```
In [220]: timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 ¬µs per loop
In [221]: np.allclose(a, n)
Out[221]: True
```

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[3]: x = numpy.random.random(100000)
In[4]: N = 1000
In[5]: %timeit result1 = numpy.convolve(x, numpy.ones((N,))/N, mode="valid")
10 loops, best of 3: 41.4 ms per loop
In[6]: %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.

```
# 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

A recipe for having fun and getting things done with the Raspberry Pi ...

12/08/2021

Roger Jennings is an author and consultant specializing in Microsoft .NET n-tier database applications and data-intensive Windows Communication Foundation (WCF) Web services with SQL Server. He’s be...

10/07/2020

Automate the Boring Stuff with Python PDF, 2nd Edition: Practical Programming for Total Beginners Illustrated Edition. The second edition of this Python bestseller (over 100,000 copies sold in prin...

22/08/2021

Taking into account the development of modern programming, especially the emerging programming languages that reflect modern practice, Numerical Programming: A Practical Guide for Scientists and...

08/08/2021

X
# Submit new EBook