ошибка при использовании функции с серией pandas в python

#python #pandas #dataframe #series

#python #pandas #фрейм данных #Серии

Вопрос:

в качестве входных данных используется массив с числами от 1 до 12. На выходе я хочу получить массив, который будет выдавать, в зависимости от числа, время года

 import pandas as pd

month = pd.Series([i for i in range(1,13)])
def mkseason(n):
    if 3<=n<=5: season = 'spring'
    elif 6<=n<=8: season = 'summer'
    elif 9<=n<=11: season = 'fall'
    elif n<=2 or n==12: season = 'winter'
    else: season = 'unknown'
    return(season)
  

В результате я хочу получить массив —

 ['winter','winter','spring','spring','spring','summer','summer','summer','fall','fall','fall','winter']
  

Когда я попытался сделать что-то подобное:

 mkseason(month)
  

Я получил ошибку. Как мне решить мою проблему? Мне нужно использовать pandas без циклов

Ответ №1:

Используйте деление по модулю с 12 и целочисленное деление для групп и последней карты на dictionary :

 month = (((month % 12) // 3).map({0:'winter',1:'spring',2:'summer',3:'fall'})
                            .fillna('unknown'))
print (month)
0     winter
1     winter
2     spring
3     spring
4     spring
5     summer
6     summer
7     summer
8       fall
9       fall
10      fall
11    winter
dtype: object
  

Подробные сведения:

 print ((month % 12) // 3)
0     0
1     0
2     1
3     1
4     1
5     2
6     2
7     2
8     3
9     3
10    3
11    0
dtype: int64
  

Производительность:

 #140k rows
#added 13 for test unknown
months = pd.Series([i for i in range(1,14)] * 10000)


In [199]: %timeit [season_for_month(m) for m in months]
58.3 ms ± 5.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [200]: %timeit (((months % 12) // 3).map({0:'winter',1:'spring',2:'summer',3:'fall'}).fillna('unknown'))
14.5 ms ± 286 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
  

Ответ №2:

Если вы хотите использовать pandas , будет работать следующее:

 import pandas as pd

def season_for_month(month: int) -> str:
    """Returns the season as a string for a given month index.

    Args:
        month: The month index.
    Returns:
        The season for the given month index
    """
    if 3 <= month <= 5:
        return 'spring'
    elif 6 <= month <= 8:
        return 'summer'
    elif 9 <= month <= 11:
        return 'fall'
    elif month <= 2 or month == 12:
        return 'winter'
    else: 
        return 'unknown'

def main():
    months = pd.Series(range(1, 13))
    seasons = [season_for_month(m) for m in months]
    print(f'months = {months}')
    print(f'seasons = {seasons}')

if __name__ == '__main__':
    main()
  

Чтобы получить сезоны в list виде строк, нам нужно использовать понимание списка, то seasons = [season_for_month(m) for m in months] есть использовать нашу функцию, season_for_month , которая принимает целое число за месяц и возвращает соответствующий сезон.