15

I have an array of the following structure which is simplified for this question:

8 2 3 4 5 6
3 6 6 7 2 6
3 8 5 1 2 9
6 4 2 7 8 3

I wish to find the minimum value in this 2D array however using the inbuilt min function returns a value error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I have looked into the alternative of using np.argmin:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmin.html

However it only evaluates along a single axis and returns the index of the minimum value along a single row/column whereas I wish to evaluate the whole array and return the lowest value not the indices.

If it is possible to return the index values of the lowest item in the array then that would be preferable also as from that the lowest value can easily be found.

EDIT: Thanks to the comments below np.min is the solution I was looking for and I was not aware of it existing so my answer is solved.

Cœur
  • 37,241
  • 25
  • 195
  • 267
cd123
  • 511
  • 1
  • 5
  • 15

3 Answers3

24

However it only evaluates along a single axis and returns the index of the minimum value along a single row/column whereas I wish to evaluate the whole array and return the lowest value not the indices.

numpy.argmin does not by default evaluate along a single axis, the default is to evaluate along the flattened matrix and it returns the linear index in the flattened array; from the numpy docs that you linked:

By default, the index is into the flattened array, otherwise along the specified axis.

Either way, use numpy.amin or numpy.min to return the minimum value, or equivalently for an array arrname use arrname.min(). As you mentioned, numpy.argmin returns the index of the minimum value (of course, you can then use this index to return the minimum value by indexing your array with it). You could also flatten into a single dimension array with arrname.flatten() and pass that into the built-in min function.

The four following methods produce what you want.

import numpy as np

values = np.array([
    [8,2,3,4,5,6],
    [3,6,6,7,2,6],
    [3,8,5,1,2,9],
    [6,4,2,7,8,3]])

values.min()          # = 1
np.min(values)        # = 1
np.amin(values)       # = 1
min(values.flatten()) # = 1
alkasm
  • 22,094
  • 5
  • 78
  • 94
16

Alternatively for a non-numpy solution:

>>> a = [[8,2,3,4,5,6],
... [3,6,6,7,2,6],
... [3,8,5,1,2,9],
... [6,4,2,7,8,3]]
>>> mymin = min([min(r) for r in a])
>>> mymin
1
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
  • 1
    It does work, but it doesn't answer the question. The OP didn't ask a non-numpy solution, so it doesn't make sense to offer a less performant one. – Imanol Luengo Jun 08 '17 at 09:26
  • 12
    @ImanolLuengo Actually, the title and question are ambiguous to whether or not numpy must used, the only numpy reference is the link and the tag. As a result this answer will be helpful for users not using numpy. The fact it is tagged numpy does not mean that only numpy answers be provided. I do not expect the answer to be accepted by the OP, however I do expect that this answer may help other users in future and that's what this site is about. – Nick is tired Jun 08 '17 at 09:27
  • To be fair, the title is the only thing that might have been ambiguous. EVERYTHING else in the question, from the tag, to the error, to the link to the documentation, to `np.argmin` points towards numpy. And yes, I do agree that this site is to help others, but there are places for everything. I could write here a tutorial to numpy that would benefit every reader, but is not the place for it. – Imanol Luengo Jun 08 '17 at 17:18
1

You can use np.min()

>>> arr = np.array([[8,2,3,4,5,6],
                    [3,6,6,7,2,6],
                    [3,8,5,1,2,9],
                    [6,4,2,7,8,3]])

>>> arr.min()
1
akash karothiya
  • 5,736
  • 1
  • 19
  • 29
  • 2
    1) numpy already has a `np.min` which is orders of magnitude faster than python's `min` and 2) reshape is not needed at all. if you use numpy – Imanol Luengo Jun 08 '17 at 09:24