关于pandas:python中的switch-case结构

Switch-case like structure in python

本问题已经有最佳答案,请猛点这里访问。

我已经完成了以下功能,它获取成员的登录日期和合同长度,并返回一个修改过的数据框,其中每个成员都有一个到期日期。函数按预期工作,但我想知道是否有更干净的方法来编写嵌套函数month_to_num(ind)。我知道python不实现cases,但是有没有办法重写所有if/elif/else语句?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def renewal_date(df):

    def month_to_num(ind):
        if (df.loc[ind,"Contract Type"] =="1 Month"):
            return 1
        elif (df.loc[ind,"Contract Type"] =="3 Months Prom" or
              df.loc[ind,"Contract Type"] =="3 Month"):
            return 3
        elif (df.loc[ind,"Contract Type"] =="4 Month Promo"):
            return 4
        elif (df.loc[ind,"Contract Type"] =="6 Months"):
            return 6
        else:
            return 12

    for z in range(0, len(df)):
        exp_date = (df.loc[z,"Date-Joined"] +
                    relativedelta(months=+month_to_num(z)))
        df.set_value(z,"Date-Renewal", exp_date)

    return df


这更适合于代码评审堆栈交换,但为了保留功能,通常使用字典:

1
2
3
4
5
6
7
8
9
10
MONTH_NUMS = {
    '1 Month': 1,
    '3 Months Prom': 3,
    '3 Month': 3,
    '4 Month Promo': 4,
    '6 Months': 6,
}

def month_to_num(ind):
    return MONTH_NUMS.get(df.loc[ind, 'Contract Type'], 12)

也就是说,这里有一点代码味道,我们是如何将字符串映射到数字的。


可以与dict.get()方法配合使用dictionary,如果dictionary中不存在键,则返回默认值。

1
2
3
4
5
6
7
8
9
10
11
12
def renewal_date(df):
    def month_to_num(ind):
        contract_types = {'1 Month': 1, '3 Months Prom': 3, '4 Month Promo': 4, '6 Months': 6}

        return contract_types.get(df.loc[ind,"Contract Type"], 12)

    for z in range(0, len(df)):
        exp_date = (df.loc[z,"Date-Joined"] +
                    relativedelta(months=+month_to_num(z)))
        df.set_value(z,"Date-Renewal", exp_date)

    return df