【发布时间】:2021-02-10 14:11:22
【问题描述】:
最初的问题
在 Python 中,我想根据 a 和 b 的值创建一个新变量 c。
if a in ('GBP', 'AUD', 'CNY', 'NZD'):
if b == '[00Y, 01Y]':
c= '90'
elif b == '[01Y, 02Y]':
c = '85'
elif b == '[02Y, 03Y]':
c = '80'
elif b == '[03Y, 04Y]':
c = '75'
elif b == '[04Y, 05Y]':
c = '70'
elif a in ('EUR', 'USD', 'CHF', 'CAD', 'SGD', 'HKD', 'JPY'):
if b == '[00Y, 01Y]':
c = '95'
elif b == '[01Y, 02Y]':
c = '90'
elif b == '[02Y, 03Y]':
c = '85'
elif b == '[03Y, 04Y]':
c = '80'
elif b == '[04Y, 05Y]':
c = '75'
elif b == '[05Y, 07Y]':
c = '60'
elif b == '[07Y, 10Y]':
c = '55'
a 和b 是数据框的列,我必须使用apply 才能最终获得我想要的。
虽然这很有效,但我认为这样一个小操作的代码很长,我想知道是否有更优雅的方法来做同样的事情。我知道np.select 条件,但它迫使我在`a 上重复条件,我发现这也不优雅。
谢谢,
问题的重新表述
我最初的问题可能不够清楚。 我想压缩以下代码而不必重复所有条件:
def f1(a, b, c, d):
if a == 1 and b <= 5 and c in ('abc', 'def') and d: s = 75
if a == 1 and b <= 5 and c in ('abc', 'def') and not d: s = 83
if a == 1 and b <= 5 and c == 'xyz' and d: s = 77
if a == 1 and b <= 5 and c == 'xyz' and not d: s = 17
if a == 1 and 5 < b <= 8 and c in ('abc', 'def') and d: s = 28
if a == 1 and 5 < b <= 8 and c in ('abc', 'def') and not d: s = 39
if a == 1 and 5 < b <= 8 and c == 'xyz' and d: s = 10
if a == 1 and 5 < b <= 8 and c == 'xyz' and not d: s = 45
if a == 1 and b > 8 and c in ('abc', 'def') and d: s = 59
if a == 1 and b > 8 and c in ('abc', 'def') and not d: s = 48
if a == 1 and b > 8 and c == 'xyz' and d: s = 29
if a == 1 and b > 8 and c == 'xyz' and not d: s = 24
if a == 2 and b <= 5 and c in ('abc', 'def') and d: s = 39
if a == 2 and b <= 5 and c in ('abc', 'def') and not d: s = 51
if a == 2 and b <= 5 and c == 'xyz' and d: s = 69
if a == 2 and b <= 5 and c == 'xyz' and not d: s = 42
if a == 2 and 5 < b <= 8 and c in ('abc', 'def') and d: s = 23
if a == 2 and 5 < b <= 8 and c in ('abc', 'def') and not d: s = 11
if a == 2 and 5 < b <= 8 and c == 'xyz' and d: s = 12
if a == 2 and 5 < b <= 8 and c == 'xyz' and not d: s = 89
if a == 2 and b > 8 and c in ('abc', 'def') and d: s = 54
if a == 2 and b > 8 and c in ('abc', 'def') and not d: s = 23
if a == 2 and b > 8 and c == 'xyz' and d: s = 22
if a == 2 and b > 8 and c == 'xyz' and not d: s = 98
if a == 3 and b <= 5 and c in ('abc', 'def') and d: s = 91
if a == 3 and b <= 5 and c in ('abc', 'def') and not d: s = 15
if a == 3 and b <= 5 and c == 'xyz' and d: s = 55
if a == 3 and b <= 5 and c == 'xyz' and not d: s = 36
if a == 3 and 5 < b <= 8 and c in ('abc', 'def') and d: s = 66
if a == 3 and 5 < b <= 8 and c in ('abc', 'def') and not d: s = 82
if a == 3 and 5 < b <= 8 and c == 'xyz' and d: s = 20
if a == 3 and 5 < b <= 8 and c == 'xyz' and not d: s = 98
if a == 3 and b > 8 and c in ('abc', 'def') and d: s = 77
if a == 3 and b > 8 and c in ('abc', 'def') and not d: s = 23
if a == 3 and b > 8 and c == 'xyz' and d: s = 41
if a == 3 and b > 8 and c == 'xyz' and not d: s = 84
return s
解决方案
我找到了这个使用itertools.product 的解决方案。但我们需要注意listvalues的顺序:
import numpy as np
import itertools
def f(a, b, c, d):
listconditions = [[a==1, a==2, a==3],
[b <= 5, 5 < b <= 8, b > 8],
[c in ("abc", "def"), c == 'xyz'],
[d, not d]]
listvalues = [75, 83, 77, 17, 28, 39, 10, 45, 59, 48, 29, 24,
39, 51, 69, 42, 23, 11, 12, 89, 54, 23, 22, 98,
91, 15, 55, 36, 66, 82, 20, 98, 77, 23, 41, 84]
allcombinations = itertools.product(*listconditions)
test = [np.logical_and.reduce(i) for i in allcombinations]
return sum(np.array(test) * listvalues)
f(1,7,'abc',False)
39
【问题讨论】:
-
能否请您澄清是否有任何答案符合您的问题,或者它们不是您所需要的。
-
所有答案都符合我的问题。谢谢大家
-
(ping) 您能否通过接受您最喜欢的答案(如果确实有)来帮助 stackoverflow 机制,以便答案的作者不会在他们的活动列表中看到这个问题;)谢谢你的参与。如果没有一个答案是相关的,请忽略这个 ping。
-
@AndrewLyashko 虽然鼓励接受答案,但不需要 OP
标签: python if-statement apply