2016-11-22 3 views
2

У меня есть три столбца в кадре данных pandas.pandas применяет функцию над столбцами dataframe с операторами if/truth

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]}) 

Я хочу, чтобы вернуть воду в год в другом столбце, который определяется как +1 года в любой день после 28 сентября, например 29 сентября 1990 года в 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 

Но я все еще возвращаю ошибки. Я также попытался лямбда-выражения (не очень хорошенькая)

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

Спасибо за любую помощь

ответ

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 

Это работает, потому что кортежи сравниваются по элементам, а месяц/день - это естественный порядок. Любое истинное условие оценивает то, что эффективно 1 и ложное условие для 0 - и мы добавляем это к году, чтобы переместить его в следующий, если потребуется.

+0

Это работает и научит меня чему-то ценному в кортежах –

+0

@JeffTilton oh - возможно, хочет '>' вместо '> =', но вы, наверное, уже заметили это :) –

Смежные вопросы