73

I have a CSV containing weather data like max and min temperatures, precipitation, longitude and latitude of the weather stations etc. Each category of data is stored in a single column.

I want to find the location of the maximum and minimum temperatures. Finding the max or min is easy: numpy.min(my_temperatures_column)

How can I find the position of where the min or max is located, so I can find the latitude and longitude?

Here is my attempt:

def coldest_location(data):

coldest_temp= numpy.min(mean_temp)

    for i in mean_temp:
         if mean_temp[i] == -24.6:
            print i

Error: List indices must be int

I saved each of the columns of my CSV into variables, so they are all individual lists.

lat          = [row[0] for row in weather_data]  # latitude
long         = [row[1] for row in weather_data]  # longitude
mean_temp    = [row[2] for row in weather_data]  # mean temperature 

I have resolved the problem as per the suggestion list.index(x)

mean_temp.index(coldest_temp) 

coldest_location=[long[5],lat[5]] 

Unsure if asking a second question within a question is proper, but what if there are two locations with the same minimum temperature? How could I find both and their indices?

James Taylor
  • 6,158
  • 8
  • 48
  • 74
julesjanker
  • 787
  • 1
  • 7
  • 9
  • If all your data are in individual lists. You can find the index number of the `min` and then use this to find the elements present in the same position on the longitude and latitude lists. If you can paste a snippet of your `csv` file it'll be easier to see – Beginner Dec 02 '14 at 23:22
  • Possible duplicate of [How to get item's position in a list?](https://stackoverflow.com/questions/364621/how-to-get-items-position-in-a-list) – Stephan Weinhold Feb 06 '18 at 07:05

9 Answers9

115

Have you thought about using Python list's .index(value) method? It return the index in the list of where the first instance of the value passed in is found.

Aaron
  • 2,367
  • 3
  • 25
  • 33
  • 1
    This doesn't seem to work when accessing those indexes within a for-loop, when looping through the regarding error (python 3). Just as a note for others (I have upvoted this answer). – cslotty Nov 05 '19 at 12:31
  • @cslotty were you able to find a solution for running an index within a loop? – iampre409 Jun 21 '20 at 17:06
  • @lampre409 If I get you right, you could use the enumerate function: https://www.programiz.com/python-programming/methods/built-in/enumerate – cslotty Jun 23 '20 at 04:22
27

Without actually seeing your data it is difficult to say how to find location of max and min in your particular case, but in general, you can search for the locations as follows. This is just a simple example below:

In [9]: a=np.array([5,1,2,3,10,4])

In [10]: np.where(a == a.min())
Out[10]: (array([1]),)

In [11]: np.where(a == a.max())
Out[11]: (array([4]),)

Alternatively, you can also do as follows:

In [19]: a=np.array([5,1,2,3,10,4])

In [20]: a.argmin()
Out[20]: 1

In [21]: a.argmax()
Out[21]: 4
James Taylor
  • 6,158
  • 8
  • 48
  • 74
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 2
    Why does `np.where()` return a list containing the array of indices, and not just the array of indices ? Could not see answer in https://numpy.org/doc/stable/reference/generated/numpy.where.html – Axel Bregnsbo Jun 14 '20 at 13:55
15

As Aaron states, you can use .index(value), but because that will throw an exception if value is not present, you should handle that case, even if you're sure it will never happen. A couple options are by checking its presence first, such as:

if value in my_list:
    value_index = my_list.index(value)

or by catching the exception as in:

try:
    value_index = my_list.index(value)
except:
    value_index = -1

You can never go wrong with proper error handling.

James Taylor
  • 6,158
  • 8
  • 48
  • 74
GaryMBloom
  • 5,350
  • 1
  • 24
  • 32
  • 3
    To your second question, you can use a "list comprehension." These can seem tricky, but once you get the hang of them, they make for very compact code. In your case: `[i for i in range(len(my_list)) if my_list[i] == value]` would return a list of the requested indeces. The list will be empty if there are no matches, or it will have one or more elements if there are matches. – GaryMBloom Feb 16 '16 at 17:54
  • 3
    Your answer could be improved by specifying that a missing value will cause `ValueError` to be thrown, so you should specifically `except ValueError:`. – supermitch Aug 11 '20 at 20:12
  • +1 Very important point: **error handling**. However, you could improve in the `except:` block because the index value `-1` is also a _valid_ index value... It could lead to confusion because `mylist[-1]` is a perfectly valid list member. A suggestion could be `value_index = float('nan')`. If the index is Not-A-Number then there is no way to get confused. – loved.by.Jesus Feb 16 '22 at 18:53
4

For your first question, find the position of some value in a list x using index(), like so:

x.index(value)

For your second question, to check for multiple same values you should split your list into chunks and use the same logic from above. They say divide and conquer. It works. Try this:

value = 1 
x = [1,2,3,4,5,6,2,1,4,5,6]

chunk_a = x[:int(len(x)/2)] # get the first half of x 
chunk_b = x[int(len(x)/2):] # get the rest half of x

print(chunk_a.index(value))
print(chunk_b.index(value))

Hope that helps!

incalite
  • 3,077
  • 3
  • 26
  • 32
2

Suppose if the list is a collection of objects like given below:

obj =  [
        {

            "subjectId" : "577a54c09c57916109142248", 
            "evaluableMaterialCount" : 0, 
            "subjectName" : "ASP.net"

        }, 
        {

            "subjectId" : "56645cd63c43a07b61c2c650", 
            "subjectName" : ".NET",         
        }, 
        {

            "subjectId" : "5656a2ec3c43a07b61c2bd83", 
            "subjectName" : "Python",

        }, 
        {

            "subjectId" : "5662add93c43a07b61c2c58c", 
            "subjectName" : "HTML"
        }
    ]

You can use the following method to find the index. Suppose the subjectId is 5662add93c43a07b61c2c58c then to get the index of the object in the list,

subjectId = "5662add93c43a07b61c2c58c"

for i, subjobj in enumerate(obj):
    if(subjectId == subjobj['subjectId']):
        print(i)
2

In the NumPy array, you can use where like this:

np.where(npArray == 20)
Ahad aghapour
  • 2,453
  • 1
  • 24
  • 33
1

You should do:

try:
    value_index = my_list.index(value)
except:
    value_index = -1;
Cristian Ramon-Cortes
  • 1,838
  • 1
  • 19
  • 32
sudhakar
  • 27
  • 1
1

There is a built in method for doing this:

numpy.where()

You can find out more about it in the excellent detailed documentation.

Ari Cooper-Davis
  • 3,374
  • 3
  • 26
  • 43
lkolololol
  • 37
  • 1
0

I would assume your variable mean_temp already has the values loaded in to it and is nX1 dimension (i.e only one row). Now to achieve what you want, you can :

Change the datatype of your variable:

def coldest_location(data):

    mean_temp = numpy.mat(mean_temp) #data is now matrix type
    min_index = numpy.nonzero(mean_temp == mean_temp.min())  # this returns list of indexes
    print mean_temp[min_index[0],min_index[1]] # printing minimum value, i.e -24.6 in you data i believe