Home > OS >  best way to map a value from range number in python?
best way to map a value from range number in python?

Time:10-28

Say we have a data example like this:

AQI LEVEL
0~50 1
51~100 2
101~150 3
151~200 4
201~300 5
>300 6

What's the best way to return the Level of AQI by given a AQI value(ex:100, return 2)

def get_level_of_aqi(aqi):
    # do sth map idea like here
    return level_of_aqi

My current method:

def get_level_of_aqi(aqi):
    if 0 <= aqi <= 50:
        level = 1
    elif 51 <= aqi <= 100:
        level = 2
    ....

    return level

Is there any better way to improve ?

CodePudding user response:

Given that the ranges aren't all equal sizes (for 1-4, the range is 50, but for 5 it is 100), you could use a generator expression with sum() like this:

def get_level_of_aqi(aqi):
    return sum(l<=aqi for l in [0, 51, 101, 151, 201, 301])

This takes advantage of True having a value of 1 and False having a value of 0

Here are example outputs:

In [1]: get_level_of_aqi(50)
Out[1]: 1

In [2]: get_level_of_aqi(100)
Out[2]: 2

In [3]: get_level_of_aqi(125)
Out[3]: 3

In [4]: get_level_of_aqi(220)
Out[4]: 5

In [5]: get_level_of_aqi(280)
Out[5]: 5

In [6]: get_level_of_aqi(310)
Out[6]: 6

CodePudding user response:

Take a look at this implementation and let me know if it works for you.

def get_level_of_aqi(aqi):
    if aqi > 0 and aqi <= 300:
        return (aqi-1)//50   1
    elif aqi >300:
        return 6
    else:
        raise Exception("Please pass positive numbers")

Please comment below if you need explanation for this. have a great day.

CodePudding user response:

How about this, it has a dict mapping.

# mapping
d = {
    1: [0, 50],
    2: [51, 100],
    3: [101, 150],
    4: [151, 200],
    5: [201, 300]
}


def get_level_of_aqi(aqi):
    if aqi < 0:
        return None

    for k, v in d.items():
        if v[0] <= aqi <= v[1]:
            return k

    return 6  # above 300


aqi = -1
level = get_level_of_aqi(aqi)
print(f'aqi: {aqi}, level: {level}')


aqi = 60
level = get_level_of_aqi(aqi)
print(f'aqi: {aqi}, level: {level}')


aqi = 500
level = get_level_of_aqi(aqi)
print(f'aqi: {aqi}, level: {level}')

# aqi: -1, level: None
# aqi: 60, level: 2
# aqi: 500, level: 6



CodePudding user response:

You can also consider using range() if you just want to do straight compare

def get_level_of_aqi(aqi):
    if aqi in range(0, 50   1):
        level = 1
    elif aqi in range(51, 100   1):
        level = 2
    elif aqi in range(101, 150   1):
        level = 3
    elif aqi in range(151, 200   1):
        level = 4
    elif aqi in range(201, 300   1):
        level = 5
    elif aqi > 300:
        level = 6
    else:
        raise Exception("Please pass positive numbers")
    return level

It may not be fancy but it's clear

CodePudding user response:

from math import ceil


def get_level_of_aqi(aqi: int):
    aqi = ceil((aqi or 1) / 50)
    aqi = aqi > 5 and aqi - 1 or aqi
    return min(aqi, 6)

CodePudding user response:

Another solution is to create a binary tree, where each node contains a value, the left branch only values smaller than and the right branch only larger than that value. If your search item is smaller/larger than the item in a branch, you continue to search in the left/right tree. This is repeated until you cannot go further. If making sure the tree is balanced (e.g., red-black tree), maximum search time is O(log(n)). Alternatively, you can use binary search. But these solutions only pay off when you have really a lot categories and irregular intervals.

CodePudding user response:

Write your if condition from heighest number.

def get_level_of_aqi(aqi):
    level = None
    if aqi > 300:
        level = 6
    elif 201 <= aqi <= 300:
        level = 5
    elif 151 <= aqi <= 200:
        level = 4
    elif 101 <= aqi <= 150:
        level = 3
    elif 51 <= aqi <= 100:
        level = 2
    elif 0 <= aqi <= 50:
        level = 1

    return level


print(get_level_of_aqi(50))
1
print(get_level_of_aqi(52))
2
print(get_level_of_aqi(4555))
6
  • Related