compressing several elif statements
我写了一些代码来找出两个时间序列之间的差异有多接近,并通过从最近的实际变化中找到与预期差异位置的距离,并根据距离来分配分数来实现这一点。
在这段代码中,我有如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | nearest_change = np.abs(actual_changes[actual_changes == change].index - time).min() minutes_off = nearest_change.seconds/60 if minutes_off < 15: sum += 1 elif minutes_off < 30: sum += .8 elif minutes_off < 45: sum += .6 elif minutes_off < 60: sum += .4 elif minutes_off < 65: sum += .2 return sum / count |
有没有一种更简洁的方法来达到这种得分?
您可以循环通过每个阈值,每次增加0.2。
1 2 3 4 5 6 | thresholds = [15, 30, 45, 60, 65] for time_diff in thresholds: if minutes_off < time_diff: sum += .2 else: break |
根据需要的数量,动态创建阈值列表可能值得。
如果您的映射是离散的,并且不能用简单的公式描述,那么您可以使用
1 2 3 4 5 6 | from collections import OrderedDict d = OrderedDict([(15,1),(30,.8),(45,.6),(60,.4),(65,.2)]) for key,value in d.items(): if minutes_off < key: s += value break |
注意,我将
是的,有。我想这一个更好,尽管它使用更多的代码来实现相同的效果,并且速度较慢。但它确实避免了重复。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class ScoreAccessDict(dict): def __init__(self, *args, f, **kwargs): self.f = f super().__init__(*args, **kwargs) def __getitem__(self, item): iterator = iter(self.keys()) try: best = next(iterator) except StopIteration: raise KeyError(item) for k in iterator: if self.f(best, item) < self.f(k, item): best = k return super().__getitem__(best) def get(self, key, default=None): try: return self[key] except KeyError: return default |
并使用它:
1 2 3 4 5 6 7 | nearest_change = np.abs(actual_changes[actual_changes == change].index - time).min() minutes_off = nearest_change.seconds / 60 # spaces between operands and the operator d = ScoreAccessDict({15: 1, 30: 0.8, 45: 0.6, 60: 0.4, 65: 0.2, float('inf'): 0}, f = lambda x, y: x if x < y else -x) return s + d[minutes_off] # sum shouldn't be shadowed |
但是从您的代码判断,所添加的值应该使用连续函数来计算。这将是最为Python式的方式。