【问题标题】:Create variable based on two other variables基于其他两个变量创建变量
【发布时间】: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


【解决方案1】:

使用 for 循环和列表来做你想做的事我假设你需要将值减少 5

tupel1 =  ('GBP', 'AUD', 'CNY', 'NZD')
tuple2 = ('EUR', 'USD', 'CHF', 'CAD', 'SGD', 'HKD', 'JPY')
listb = ['[00Y, 01Y]' ,'[02Y, 03Y]','[03Y, 04Y]','[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)
  
 

【讨论】:

  • 进行类型转换
  • 小错字:tuple1 和 tuple2 是最初定义的,但 tuble 在代码块中使用。
【解决方案2】:

您可以使用字典来包含 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]

【讨论】:

  • 条件比较时有没有类似的方法?
  • @PierreYvesCorre 你能举例说明你的意思吗?
【解决方案3】:

另一种说法,单线:

(95 if a in {'EUR', 'USD', 'CHF', 'CAD', 'SGD', 'HKD', '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, 1, 2, 3, 4, 5, 7].index(int(b[1:3]))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-26
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多