python/pandas:将月份int转换为月份名称

Boo*_*d16 20 python date monthcalendar dataframe pandas

我发现的大部分信息都不在python> pandas> dataframe中,因此问题.

我想将1到12之间的整数转换为一个明确的月份名称.

我有一个df看起来像:

   client Month
1  sss    02
2  yyy    12
3  www    06
Run Code Online (Sandbox Code Playgroud)

我希望df看起来像这样:

   client Month
1  sss    Feb
2  yyy    Dec
3  www    Jun
Run Code Online (Sandbox Code Playgroud)

Eoi*_*inS 23

你可以通过组合calendar.month_abbr和有效地做到这一点df[col].apply()

import calendar
df['Month'] = df['Month'].apply(lambda x: calendar.month_abbr[x])
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此解决方案类似于 Python 级循环中的 `list.__getitem__`,即它没有利用 Pandas 可用的矢量化功能。根据 [this answer](/sf/answers/3801711861/),提取到字典然后映射效率更高。 (2认同)
  • 当你有 pandas 自己的 Month_name() 函数时,我认为这不是一个好主意。 (2认同)

tod*_*day 16

由于月份缩写是他们全名的前三个字母,我们可以先将Month列转换为datetime然后使用dt.month_name()得到完整的月份名称,最后使用str.slice()方法获得前三个字母,全部使用pandas并且只在一行代码:

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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“.str.slice(stop=3)”可以简化为“.str[:3]” (4认同)

jpp*_*jpp 10

calendar模块很有用,但calendar.month_abbr类似于数组:它不能直接以矢量化方式使用。为了实现有效的映射,您可以构造一个字典,然后使用pd.Series.map

import calendar
d = dict(enumerate(calendar.month_abbr))
df['Month'] = df['Month'].map(d)
Run Code Online (Sandbox Code Playgroud)

性能基准测试显示约 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
Run Code Online (Sandbox Code Playgroud)


Dat*_*ice 10

使用日期时间对象方法

我很惊讶这个答案没有使用解决方案strftime

请注意,在使用该方法之前,您需要有一个有效的日期时间对象strftime,用于pd.to_datetime(df['date_column'])将目标列转换为日期时间对象。

import pandas as pd 

dates = pd.date_range('01-Jan 2020','01-Jan 2021',freq='M')

df = pd.DataFrame({'dates' : dates})
df['month_name'] = df['dates'].dt.strftime('%b')

   dates month_name
0  2020-01-31        Jan
1  2020-02-29        Feb
2  2020-03-31        Mar
3  2020-04-30        Apr
4  2020-05-31        May
5  2020-06-30        Jun
6  2020-07-31        Jul
7  2020-08-31        Aug
8  2020-09-30        Sep
9  2020-10-31        Oct
10 2020-11-30        Nov
11 2020-12-31        Dec
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用对名称进行切片dt.month_name()

df['month_name_str_slice'] = df['dates'].dt.month_name().str[:3]

        dates month_name month_name_str_slice
0  2020-01-31        Jan                  Jan
1  2020-02-29        Feb                  Feb
2  2020-03-31        Mar                  Mar
3  2020-04-30        Apr                  Apr
4  2020-05-31        May                  May
5  2020-06-30        Jun                  Jun
6  2020-07-31        Jul                  Jul
7  2020-08-31        Aug                  Aug
8  2020-09-30        Sep                  Sep
9  2020-10-31        Oct                  Oct
10 2020-11-30        Nov                  Nov
11 2020-12-31        Dec                  Dec
Run Code Online (Sandbox Code Playgroud)


and*_*rew 6

您可以使用列应用轻松完成此操作。

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
Run Code Online (Sandbox Code Playgroud)


Suh*_*ote 6

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

df['Month'] = df['Month'].apply(mapper)
Run Code Online (Sandbox Code Playgroud)

参考:


pek*_*apa 5

一种方法是使用apply数据框中的方法,但要做到这一点,您需要一张地图来转换月份。您可以使用函数/字典或Python自己的日期时间来做到这一点。

对于日期时间,它会是这样的:

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)
Run Code Online (Sandbox Code Playgroud)


以类似的方式,您可以为自定义名称构建自己的地图。它看起来像这样:

months_map = {01: 'Jan', 02: 'Feb'}
def mapper(month):
    return months_map[month]
Run Code Online (Sandbox Code Playgroud)


显然,您不需要显式定义此函数,可以lambda直接在 apply 方法中使用。


小智 5

其用途strptime和功能:lambda

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