python/pandas: конвертировать месяц int в месяц имя

Большая часть информации, которую я нашел, не была в python> pandas> dataframe, следовательно, вопрос.

Я хочу преобразовать целое число от 1 до 12 в сокращенное название месяца.

У меня есть df, который выглядит так:

   client Month
1  sss    02
2  yyy    12
3  www    06

Я хочу, чтобы df выглядел так:

   client Month
1  sss    Feb
2  yyy    Dec
3  www    Jun

Ответы

Ответ 1

Вы можете сделать это эффективно, объединив calendar.month_abbr и df[col].apply()

import calendar
df['Month'] = df['Month'].apply(lambda x: calendar.month_abbr[x])

Ответ 2

Один из способов сделать это - apply метод apply в dataframe, но для этого вам нужна карта для преобразования месяцев. Вы можете либо сделать это с помощью функции/словаря, либо с помощью собственного времени и времени Python.

С datetime это будет что-то вроде:

def mapper(month):
    date = datetime.datetime(2000, month, 1)  # You need a dateobject with the proper month
    return date.strftime('%b')  # %b returns the months abbreviation, other options [here][1]

df['Month'].apply(mapper)


Аналогичным образом вы можете создать свою собственную карту для пользовательских имен. Это будет выглядеть так:

months_map = {01: 'Jan', 02: 'Feb'}
def mapper(month):
    return months_map[month]


Очевидно, что вам не нужно явно определять эти функции и использовать lambda непосредственно в методе apply.

Ответ 3

Для этого используйте strptime и lambda функцию:

from time import strptime
df['Month'] = df['Month'].apply(lambda x: strptime(x,'%b').tm_mon) 

Ответ 4

Вы можете сделать это легко, используя столбец.

import pandas as pd

df = pd.DataFrame({'client':['sss', 'yyy', 'www'], 'Month': ['02', '12', '06']})

look_up = {'01': 'Jan', '02': 'Feb', '03': 'Mar', '04': 'Apr', '05': 'May',
            '06': 'Jun', '07': 'Jul', '08': 'Aug', '09': 'Sep', '10': 'Oct', '11': 'Nov', '12': 'Dec'}

df['Month'] = df['Month'].apply(lambda x: look_up[x])
df

  Month client
0   Feb    sss
1   Dec    yyy
2   Jun    www

Ответ 5

Протестировав все это на большом наборе данных, я обнаружил, что следующее является самым быстрым:

import calendar
def month_mapping():
    # I'm lazy so I have a stash of functions already written so
    # I don't have to write them out every time. This returns the
    # {1:'Jan'....12:'Dec'} dict in the laziest way...
    abbrevs = {}
    for month in range (1, 13):
        abbrevs[month] = calendar.month_abbr[month]
    return abbrevs

abbrevs = month_mapping()

df['Month Abbrev'} = df['Date Col'].dt.month.map(mapping)

Ответ 6

Поскольку сокращенные названия месяцев - это первые три буквы их полных имен, мы могли бы сначала преобразовать столбец Month в datetime а затем использовать dt.month_name() чтобы получить полное имя месяца, и, наконец, использовать str.slice() чтобы получить первые три буквы, все с использованием панд и только в одной строке кода:

df['Month'] = pd.to_datetime(df['Month'], format='%m').dt.month_name().str.slice(stop=3)

df

  Month client
0   Feb sss
1   Dec yyy
2   Jun www

Ответ 7

Модуль calendar полезен, но calendar.month_abbr похож на массив: его нельзя использовать в векторизованном виде. Для эффективного отображения вы можете создать словарь и затем использовать pd.Series.map:

import calendar
d = dict(enumerate(calendar.month_abbr))
df['Month'] = df['Month'].map(d)

Сравнительный анализ производительности показывает разницу в производительности в ~ 130 раз:

import calendar

d = dict(enumerate(calendar.month_abbr))
mapper = calendar.month_abbr.__getitem__

np.random.seed(0)
n = 10**5
df = pd.DataFrame({'A': np.random.randint(1, 13, n)})

%timeit df['A'].map(d)       # 7.29 ms per loop
%timeit df['A'].map(mapper)  # 946 ms per loop

Ответ 8

def mapper(month):
   return month.strftime('%b') 

df['Month'] = df['Month'].apply(mapper)

Ссылка: