pandas使用if / truth语句在dataframe列上应用函数

时间:2016-11-22 17:12:37

标签: python pandas lambda

我在pandas数据框中有三列。

df = pd.DataFrame({'month':[1,2,3,4,5,6,7,8,9,10,11,12],
                   'day':[10,23,16,30,1,23,3,28,29,1,4,2],
                    'year':[1990,1990,1990,1990,1990,1990,1990,1990,1990,1990,1990,1990]})

我想在9月28日之后的任何一天将另一列定义为年+1,以便返回水年。例如,1990年9月29日是1991年的水年。

我有一个可以独立工作的功能

def wy(month, day, year):
    if month >8 and day > 28:
        year = year + 1
    else:
        if month>9:
            year = year + 1
        else:
            year = year
    return year
wy(9,30,2000)

但是

df['wy'] = wy(df['month'],df['day'],df['year'])

返回错误

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

当我尝试将其应用于数据帧时。我查看了文档和其他问题,并尝试了其他多种功能,例如

def wy(month, day, year):
    if any(month >8 & day > 28):
        year = year + 1
    else:
        if any(month>9):
            year = year + 1
        else:
            year = year
    return year


def wy(month, day, year):
    if any((month >8 & day > 28)|month>9):
        year = year + 1
    return year

但我还在回复错误。我也试过一个lambda表达式(不是很漂亮)

df['wy'] = (lambda x,y,z:z+1 if (x >8 & y > 28)|y>9 else z, df['month'],df['day'],df['year'])

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

您可以使用(month, day)的元组并与列轴上应用的元组进行比较,例如:

df = pd.DataFrame({'month':[1,2,3,4,5,6,7,8,9,10,11,12],
                   'day':[10,23,16,30,1,23,3,28,29,1,4,2],
                    'year':[1990,1990,1990,1990,1990,1990,1990,1990,1990,1990,1990,1990]})

使用:

df.apply(lambda L: L.year + ((L.month, L.day) >= (9, 28)), axis=1)

给你:

0     1990
1     1990
2     1990
3     1990
4     1990
5     1990
6     1990
7     1990
8     1991
9     1991
10    1991
11    1991
dtype: int64

这是有效的,因为元组是逐元素比较的,月/日是自然顺序。任何真实条件都会评估有效10的错误条件 - 我们会将其添加到年份,以便在需要时将其移至下一个。