Reputation:
I have two different variables that can each have a different value between -1 and 1.
I want to be able to map each variable to their corrosponding string, based on their value being within a certain range, so for example:
var_a = 0.34
var_b = 0.94
# var_a ranges:
if var_a is between -0.1 and 0.1, then var_a = 'pink'
if var_a is between 0.1 and 0.35, then var_a = 'red'
...
# thus var_a = 'red'
# var_b ranges:
if var_b is between 0 and 1.0, then var_b = 'yellow'
if var_b is between -1.0 and -0.01, then var_b = 'lilac'
...
# thus var_b = 'yellow'
I have been able to do the above with if
statements, but there's a large number of them and so it feels like there must be a better solution (trying to do this in Python).
Upvotes: 2
Views: 2997
Reputation: 420
An alternative to the chain of if
s is working with a dictionary mapping functions (lambdas, if you might) to the values you want. So, using your example:
d = {(lambda x: -0.1 < x <= 0.1): 'pink', (lambda x: 0.1 < x <= 0.35): 'red'}
var_a = 0.2
for check in d:
if check(var_a):
var_a = d[check]
break
This is nice if you're looking for a clean, concise and understandable solution.
Upvotes: 0
Reputation: 402333
You can do this really easily using the IntervalIndex
API in pandas.
import pandas as pd
labels = ['pink', 'red']
idx = pd.IntervalIndex.from_breaks([-0.1, 0.1, 0.35], closed='left')
labels[idx.get_loc(0.34)]
# 'red'
Indexing is logarithmic time complexity for a given value (as opposed to all other solutions here, which are linear time). If you need to retrieve multiple indices, or if you need to handle out-of-bounds ranges, use idx.get_indexer
.
Upvotes: 2
Reputation: 16495
One solution could be something like this:
def get_color(var_name, value):
the_ranges = {
'var_a': [
(-0.1, 0.1 , 'pink'),
( 0.1, 0.35, 'red'),
],
'var_b': [
( 0 , 1.0 , 'yellow'),
(-1.0, -0.01, 'lilac'),
],
}
for v_min, v_max, color in the_ranges[var_name]:
if v_min <= value <= v_max:
return color
raise ValueError('nothing found for {} and value {}'.format(var_name, value))
This could be used like this:
>>> get_color('var_a', 0.34)
'pink'
>>> get_color('var_b', 0.94)
'yellow'
This has the advantage that the value ranges are (mostly) easy to read and all in one place (no if
statements inbetween); This can be helpful when there are lots of variables and ranges to define.
Upvotes: 0
Reputation: 8636
This will work
ranges = {
'red': (-1, 0),
'blue': (0, 0.5),
'pink': (0.5, 1),
}
var_x = 0.7
for name, range in ranges.items():
if range[0] <= var_x <= range[1]:
var_x = name
break
print (var_x)
Upvotes: 4