python/pandas: 将月份转换为月份名称
python/pandas: convert month int to month name
我发现的大部分信息都不在 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
您可以使用应用列轻松完成此操作。
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
一种方法是使用数据框中的 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)
以类似的方式,您可以为自定义名称构建自己的地图。它看起来像这样:
months_map = {01: 'Jan', 02: 'Feb'}
def mapper(month):
return months_map[month]
显然,您不需要显式定义此函数,可以直接在 apply 方法中使用 lambda
。
您可以通过组合 calendar.month_abbr
和 df[col].apply()
高效地完成此操作
import calendar
df['Month'] = df['Month'].apply(lambda x: calendar.month_abbr[x])
为此使用 strptime
和 lambda
函数:
from time import strptime
df['Month'] = df['Month'].apply(lambda x: strptime(x,'%b').tm_mon)
在大型数据集上测试了所有这些后,我发现以下是最快的:
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)
由于缩写的月份名称是其全名的前三个字母,我们可以先将 Month
列转换为 datetime
,然后使用 dt.month_name()
获得完整的月份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
calendar
module is useful, but 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
def mapper(month):
return month.strftime('%b')
df['Month'] = df['Month'].apply(mapper)
参考:
您可以使用Pandas month_name()
功能。示例:
>>> idx = pd.date_range(start='2018-01', freq='M', periods=3)
>>> idx
DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31'],
dtype='datetime64[ns]', freq='M')
>>> idx.month_name()
Index(['January', 'February', 'March'], dtype='object')
有关更多详细信息,请访问 this link。
假设我们有一个这样的DF,并且日期已经是日期时间格式:
df.head(3)
value
date
2016-05-19 19736
2016-05-26 18060
2016-05-27 19997
然后我们可以像这样轻松地提取月份编号和月份名称:
df['month_num'] = df.index.month
df['month'] = df.index.month_name()
value year month_num month
date
2017-01-06 37353 2017 1 January
2019-01-06 94108 2019 1 January
2019-01-05 77897 2019 1 January
2019-01-04 94514 2019 1 January
使用日期时间对象方法
我很惊讶这个答案没有使用 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
另一种方法是使用 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
最好的方法是按照
的评论使用 month_name()
Nurul Akter Towhid.
df['Month'] = df.Month.dt.month_name()
我发现的大部分信息都不在 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
您可以使用应用列轻松完成此操作。
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
一种方法是使用数据框中的 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)
以类似的方式,您可以为自定义名称构建自己的地图。它看起来像这样:
months_map = {01: 'Jan', 02: 'Feb'}
def mapper(month):
return months_map[month]
显然,您不需要显式定义此函数,可以直接在 apply 方法中使用 lambda
。
您可以通过组合 calendar.month_abbr
和 df[col].apply()
import calendar
df['Month'] = df['Month'].apply(lambda x: calendar.month_abbr[x])
为此使用 strptime
和 lambda
函数:
from time import strptime
df['Month'] = df['Month'].apply(lambda x: strptime(x,'%b').tm_mon)
在大型数据集上测试了所有这些后,我发现以下是最快的:
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)
由于缩写的月份名称是其全名的前三个字母,我们可以先将 Month
列转换为 datetime
,然后使用 dt.month_name()
获得完整的月份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
calendar
module is useful, but 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
def mapper(month):
return month.strftime('%b')
df['Month'] = df['Month'].apply(mapper)
参考:
您可以使用Pandas month_name()
功能。示例:
>>> idx = pd.date_range(start='2018-01', freq='M', periods=3)
>>> idx
DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31'],
dtype='datetime64[ns]', freq='M')
>>> idx.month_name()
Index(['January', 'February', 'March'], dtype='object')
有关更多详细信息,请访问 this link。
假设我们有一个这样的DF,并且日期已经是日期时间格式:
df.head(3)
value
date
2016-05-19 19736
2016-05-26 18060
2016-05-27 19997
然后我们可以像这样轻松地提取月份编号和月份名称:
df['month_num'] = df.index.month
df['month'] = df.index.month_name()
value year month_num month
date
2017-01-06 37353 2017 1 January
2019-01-06 94108 2019 1 January
2019-01-05 77897 2019 1 January
2019-01-04 94514 2019 1 January
使用日期时间对象方法
我很惊讶这个答案没有使用 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
另一种方法是使用 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
最好的方法是按照
的评论使用 month_name()
Nurul Akter Towhid.
df['Month'] = df.Month.dt.month_name()