我有一个问题,我需要确定值在其他值之间的位置。这是一个非常长的问题......但它是一个令人费解的问题(至少对我而言)。
使用以下数据可以看到问题的最简单的表述:
我的值为24.0。我需要确定该值在六个范围内的位置'。范围是:10,20,30,40,50,60。我需要计算沿着范围的位置,值着陆。我可以看到它落在20到30之间。一个简单的if语句可以为我找到。
我检查该值是否在20到30之间的if语句将是:
if value >=20 and value <=30:
非常简单的东西。
我遇到麻烦的是当我尝试对输出进行排名时。
作为一个例子,让我们说每个范围值都给出一个整数表示。 10 = 1,20 = 2,30 = 3,40 = 4,50 = 5,60 = 6,70 = 7。另外,假设如果该值小于两个值之间的中点,则为其分配较低值的等级输出。例如,我的值24在20到30之间,所以它应该被排列为&#34; 2&#34;。
对于这个例子,这本身就相当简单,但是使用真实世界的数据,我有以下范围和值:
另一个皱纹 - 范围的顺序很重要。在上文中,第一个范围数字等于1的排名,第二个等级排名为2等,正如我上面提到的几段。
范围值中的负数引起了麻烦,直到我决定使用百分位数排名来消除所有负值。为此,我使用Map each list value to its corresponding percentile这样的答案:
y=[stats.percentileofscore(x, a, 'rank') for a in x]
其中x是范围和值I&#39; m。通过这个运行值= 6的值导致y为:
x = [1, 40, 35, 30, 5, 3, 0, 6]
y=[stats.percentileofscore(x, a, 'rank') for a in x]
看着&#34; y&#34;,我们将其视为:
[25.0, 100.0, 87.5, 75.0, 50.0, 37.5, 12.5, 62.5]
我现在需要做的是将最后一个值(62.5)与其他值进行比较,以根据以下排名地图查看最终排名(排名为1到7):
1=25.0
2=100.0
3=87.5
4=75.0
5=50.0
6=37.5
7=12.5
如果值介于两个值之间,则应为其分配 lower 排名。在此示例中,62.5值的最终排名值为4,因为它位于75.0(rank = 4)和50.0(rank = 5)之间。
如果我采取&#39; y&#39;并将其分解并在多个if / else语句中使用这些值,它适用于某些但不是全部(-13示例不正常工作)。
我的问题是:
如何在不构建庞大的if / elif结构的情况下,以编程方式分析任何值/范围集来查找最终排名?以下是一些示例集。排名按以下顺序排列(范围中的第一个值= 1,第二个= 2等等)
我可能会在python中遗漏一些非常容易的事情来做这件事......但是我已经在这堵墙上撞了几天而没有任何进展。
感谢任何帮助/指示。
答案 0 :(得分:2)
def checker(term):
return term if term >= 0 else abs(term)+1e10
l1, v1 = [5, 35, 30, 25, -25, -30, -35], -13 # Desired: 4
l2, v2 = [5, 70, 65, 60, 40, 35, 30], 50 # Desired: 4
l3, v3 = [1, 40, 35, 30, 5, 3, 0], 6 # Desired: 4
l4, v4 = [10, 20, 30, 40, 50, 60, 70], 24 # Desired: 2
l5, v5 = [0.1, 0.55, 0.65, 0.75, 1.75, 1.85, 1.95], 2.26 # Desired: 7
l6, v6 = [10, 20, 30, 40, 60, 70, 80], 31 # Desired: 3
结果:
>>> print(*(sorted(l_+[val], key=checker).index(val) for
... l_, val in zip((l1,l2,l3,l4,l5,l6),(v1,v2,v3,v4,v5,v6))), sep='\n')
4
4
4
2
7
3
答案 1 :(得分:1)
以-13
的第一个例子为例。
y = [5, 35, 30, 25, -25, -30, -35]
value_to_check = -13
max_rank = len(y) # Default value in case no range found (as per 2.26 value example)
for ii in xrange(len(y)-1,0,-1):
if (y[ii] <= value_to_check <= y[ii-1]) or (y[ii] >= value_to_check >= y[ii-1]):
max_rank = ii
break
>>> max_rank
4
以函数形式:
def get_rank(y, value_to_check):
max_rank = len(y) # Default value in case no range found (as per 2.26 value example)
for ii in xrange(len(y)-1,0,-1):
if (y[ii] <= value_to_check <= y[ii-1]) or (y[ii] >= value_to_check >= y[ii-1]):
max_rank = ii
break
return max_rank
致电时:
>>> get_rank(y, value_to_check)
4
答案 2 :(得分:1)
这正确地找到了所有数据的答案:
def get_rank(l,n):
mindiff = float('inf')
minindex = -1
for i in range(len(l) - 1):
if l[i] <= n <= l[i + 1] or l[i + 1] <= n <= l[i]:
diff = abs(l[i + 1] - l[i])
if diff < mindiff:
mindiff = diff
minindex = i
if minindex != -1:
return minindex + 1
if n > max(l):
return len(l)
return 1
>>> test()
[5, 35, 30, 25, -25, -30, -35] -13 Desired: 4 Actual: 4
[5, 70, 65, 60, 40, 35, 30] 50 Desired: 4 Actual: 4
[1, 40, 35, 30, 5, 3, 0] 6 Desired: 4 Actual: 4
[10, 20, 30, 40, 50, 60, 70] 24 Desired: 2 Actual: 2
[0.1, 0.55, 0.65, 0.75, 1.75, 1.85, 1.95] 2.26 Desired: 7 Actual: 7
[10, 20, 30, 40, 60, 70, 80] 31 Desired: 3 Actual: 3
为了完整性,这是我的test()
功能,但您只需要get_rank
来处理您的工作:
>>> def test():
lists = [[[5, 35, 30, 25, -25, -30, -35],-13,4],[[5, 70, 65, 60, 40, 35, 30],50,4],[[1, 40, 35, 30, 5, 3,0],6,4],[[10, 20, 30, 40, 50, 60, 70],24,2],[[0.1, 0.55, 0.65, 0.75, 1.75, 1.85, 1.95],2.26,7],[[10, 20, 30, 40, 60, 70, 80],31,3]]
for l,n,desired in lists:
print l,n,'Desired:',desired,'Actual:',get_rank(l,n)