如何解决根据其他两个变量创建变量
初始问题
在Python中,我想基于c
和a
的值创建一个新变量b
。
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,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,51,69,42,23,11,12,89,54,22,98,91,15,55,36,66,82,20,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
解决方法
您可以使用字典来包含a
的索引和b
中的值:
options_a = {'GBP': 0,'AUD': 0,'CNY': 0,'NZD': 0,'EUR': 1,'USD': 1,'CHF': 1,'CAD': 1,'SGD': 1,'HKD': 1,'JPY': 1}
options_b = {'[00Y,01Y]': ('90','95'),'[01Y,02Y]': ('85','90'),'[02Y,03Y]': ('80','85'),'[03Y,04Y]': ('75','80'),'[04Y,05Y]': ('70','75'),'[05Y,07Y]': (None,'60'),'[07Y,10Y]': (None,'55')}
# Get the index of the tuple by looking up 'a' first
idx = options_a[a]
# Then use that index when you look up 'b' to grab the correct value for 'c'
c = options_b[b][idx]
如果您获得了您不打算使用的任何组合,则会产生一个KeyError
,您可能会或可能不想处理:
try:
idx = options_a[a]
tup = options_b[b]
except KeyError:
print("Do something")
else:
c = tup[idx]
,
使用for循环和列表做您想要的事情,我假设您需要将值减少5
tupel1 = ('GBP','AUD','CNY','NZD')
tuple2 = ('EUR','USD','CHF','CAD','SGD','HKD','JPY')
listb = ['[00Y,01Y]',03Y]',04Y]',05Y]',]
for i in range(listb):
if listb[i]==b:
if a in tuble1:
c = str(90 - 5*i)
elif a in tuble2:
c = str(95 -5*i)
,
另一种选择,单线:
(95 if a in {'EUR','JPY'} else 90) - 5 * [0,1,2,3,4,5,7].index(int(b[1:3]))
或者将其包装得更多,但会变脏:
(95 if a in 'EUR USD CHF CAD SGD HKD JPY' else 90) - 5 * [0,7].index(int(b[1:3]))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。