首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用映射代替if- python来提高python中的程序速度?

如何使用映射代替if- python来提高python中的程序速度?
EN

Stack Overflow用户
提问于 2020-03-13 12:08:31
回答 2查看 62关注 0票数 0

我编写了一个程序,根据频率和预定义的速率计算一些速率。当我完成我的程序时,有人在看到我的代码后告诉我,您应该尝试应用映射概念,而不是那么多if-else语句。我不知道映射概念,所以我从互联网上读到了它,我发现它非常有趣,因为它在我们的程序中的作用就像哈希函数,它可以提高代码到O(1)而不是O(n)的效率。但是我在应用这个的时候遇到了一些麻烦。示例数据(实际上共有36288行2列):

代码语言:javascript
复制
frequency   acp
49.96       324.50
49.99       324.50
49.98       324.50
50.00       324.50
49.98       324.50
49.94       324.50
49.96       324.50
49.96       324.50
49.93       324.50
49.95       324.50
50.00       324.50
49.99       324.50
49.99       324.50
49.98       324.50
49.99       324.50
50.03       324.50
49.98       324.50
50.02       324.50
49.99       324.50
49.98       324.50
49.98       324.50
49.99       324.50
49.95       324.50
49.96       324.50

我以前的计划:

代码语言:javascript
复制
import pandas as pd
import time
start = time.time()
hourlyDF = pd.read_excel("main_input.xlsx")
frequency = hourlyDF['frequency']
acp = hourlyDF['acp']
results = []
for each, acp in zip(frequency, acp):
            if each >= 50.05:
                rate = 0
                results.append(rate)
            elif each < 50.05 and each >= 50.04:
                rate = acp * 0.2
                results.append(rate)
            elif each < 50.04 and each >= 50.03:
                rate = acp * 0.4
                results.append(rate)
            elif each < 50.03 and each >= 50.02:
                rate = acp * 0.6
                results.append(rate)
            elif each < 50.02 and each >= 50.01:
                rate = acp * 0.8
                results.append(rate)
            elif each < 50.01 and each >= 50.00:
                rate = acp
                results.append(rate)
            elif each < 50.00 and each >= 49.99:
                rate = 50 + 15 * acp / 16
                results.append(rate)
            elif each < 49.99 and each >= 49.98:
                rate = 100 + 14 * acp / 16
                results.append(rate)
            elif each < 49.98 and each >= 49.97:
                rate = 150 + 13 * acp / 16
                results.append(rate)
            elif each < 49.97 and each >= 49.96:
                rate = 200 + 12 * acp / 16
                results.append(rate)
            elif each < 49.96 and each >= 49.95:
                rate = 250 + 11 * acp / 16
                results.append(rate)
            elif each < 49.95 and each >= 49.94:
                rate = 300 + 10 * acp / 16
                results.append(rate)
            elif each < 49.94 and each >= 49.93:
                rate = 350 + 9 * acp / 16
                results.append(rate)
            elif each < 49.93 and each >= 49.92:
                rate = 400 + 8 * acp / 16
                results.append(rate)
            elif each < 49.92 and each >= 49.91:
                rate = 450 + 7 * acp / 16
                results.append(rate)
            elif each < 49.91 and each >= 49.90:
                rate = 500 + 6 * acp / 16
                results.append(rate)
            elif each < 49.90 and each >= 49.89:
                rate = 550 + 5 * acp / 16
                results.append(rate)
            elif each < 49.89 and each >= 49.88:
                rate = 600 + 4 * acp / 16
                results.append(rate)
            elif each < 49.88 and each >= 49.87:
                rate = 650 + 3 * acp / 16
                results.append(rate)
            elif each < 49.87 and each >= 49.86:
                rate = 700 + 2 * acp / 16
                results.append(rate)
            elif each < 49.86 and each >= 49.85:
                rate = 750 + acp / 16
                results.append(rate)
            elif each < 49.85:
                rate = 800
                results.append(rate)
print("rate: ", results)
print("\ntime taken: ", time.time()-start)

我的方法(实际上我不知道具体如何处理):

代码语言:javascript
复制
import pandas as pd
import time
start = time.time()

hourlyinputDF = pd.read_excel("main_input.xlsx")

frequency = hourlyinputDF['frequency']
acp = hourlyinputDF['acp']

#Creating a Mapping Function
for rate in acp:
    frequencyMapFunction = {
        50.05: 0, 50.04: rate*0.2, 50.03: rate*0.4, 50.02: rate*0.6, 50.01: rate*0.8, 50.00: rate, 49.99: 50+15*rate/16,
        49.98: 100+14*rate/16, 49.97: 150+13*rate/16, 49.96: 200+12*rate/16, 49.95: 250+11*rate/16, 49.94: 300+10*rate/16,
        49.93: 350+9*rate/16, 49.92: 400+8*rate/16, 49.91: 450+7*rate/16, 49.90: 500+6*rate/16, 49.89: 550+5*rate/16,
        49.88: 600+4*rate/16, 49.87: 650+3*rate/16, 49.86: 700+2*rate/16, 49.85: 750+rate/16
        #less than 49.85 is not included because idk how to include it
                            }

for i in frequency:
    print("rate: ", frequencyMapFunction[i])

print("time taken: ", time.time()-start)

旧程序完全正常工作,但我想了解如何将映射概念应用到我的特定案例中。谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-13 12:43:42

如果您有一组值,并且需要将每个值与其他值关联,尤其是在没有关联的逻辑/模式时,映射是很好的。

您的问题在以下两个方面不符合此标准:

  1. 您没有要映射的“值集”;您有一组值范围(
  2. ),您确实有可被利用的模式。

因此,您的费率计算可以这样实现:

代码语言:javascript
复制
def calc_rate( each, acp ):
    if each >= 50.05:
        return 0
    if each >= 50.01:
        return (5005 - floor(each*100)) * acp * 0.2
    if each >= 49.85:
        bkt = 5000 - floor(each*100)
        return 50*bkt + ((16-bkt) * acp / 16)
    return 800

您可以用映射替换这两个公式,但坦率地说,我看不到这样做的好处。

票数 1
EN

Stack Overflow用户

发布于 2020-03-13 12:18:26

在检查是否相等时,可以替换如下代码片段:

代码语言:javascript
复制
x = something_that_returns_int()

if x == 1:
  print('a')
elif x == 2:
  print('b')
elif x == 3:
  print('c')
else:
  print('unknown')

对此:

代码语言:javascript
复制
mapping = {
  1: 'a',
  2: 'b',
  3: 'c',
}

x = something_that_returns_int()

# pick one of them
letter = mapping[x]
letter = mapping.get(x, 'unknown')
try:
  letter = mapping[x]
except KeyError:
  letter = 'unknown'

print(letter)

如果将ifelif>运算符一起使用,则可以循环执行映射:

代码语言:javascript
复制
mapping_below = {
  10: 'below 10',
  20: 'between 10 and 20',
  30: 'between 20 and 30',
}

x = something_that_returns_int()
for key in mapping_below():
  if x < key:
    print(mapping_below[key])
    break
else:  # when break was never called, so we have looped through entire mapping
  print('above 30')

希望这会有所帮助:)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60670225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档