我正在尝试创建一个函数,可以将月份数字转换为缩写月份名称或将缩写月份名称转换为月份数字。我认为这可能是一个常见问题,但我在网上找不到。
我正在考虑日历模块。我发现要将月份数字转换为缩写月份名称,您只需执行
calendar.month_abbr[num]
即可。但我看不出有什么办法可以朝另一个方向走。创建一个字典来转换另一个方向是处理这个问题的最佳方法吗?或者是否有更好的方法从月份名称到月份编号,反之亦然?
使用
calendar
模块创建反向字典(与任何模块一样,您需要导入):
{month: index for index, month in enumerate(calendar.month_abbr) if month}
在 2.7 之前的 Python 版本中,由于该语言不支持字典理解语法,您必须这样做
dict((month, index) for index, month in enumerate(calendar.month_abbr) if month)
只是为了好玩:
from time import strptime
strptime('Feb','%b').tm_mon
还有另一种方法。
def monthToNum(shortMonth):
return {
'jan': 1,
'feb': 2,
'mar': 3,
'apr': 4,
'may': 5,
'jun': 6,
'jul': 7,
'aug': 8,
'sep': 9,
'oct': 10,
'nov': 11,
'dec': 12
}[shortMonth]
信息来源:Python文档
要从月份名称获取月份编号,请使用日期时间模块
import datetime
month_number = datetime.datetime.strptime(month_name, '%b').month
# To get month name
In [2]: datetime.datetime.strftime(datetime.datetime.now(), '%a %b %d, %Y')
Out [2]: 'Thu Aug 10, 2017'
# To get just the month name, %b gives abbrevated form, %B gives full month name
# %b => Jan
# %B => January
dateteime.datetime.strftime(datetime_object, '%b')
这里有一个更全面的方法,也可以接受完整的月份名称
def month_string_to_number(string):
m = {
'jan': 1,
'feb': 2,
'mar': 3,
'apr':4,
'may':5,
'jun':6,
'jul':7,
'aug':8,
'sep':9,
'oct':10,
'nov':11,
'dec':12
}
s = string.strip()[:3].lower()
try:
out = m[s]
return out
except:
raise ValueError('Not a month')
示例:
>>> month_string_to_number("October")
10
>>> month_string_to_number("oct")
10
还有一个:
def month_converter(month):
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
return months.index(month) + 1
完整的月份名称到月份编号(例如January、February等..):
import datetime
month_name = 'January'
month_num = datetime.datetime.strptime(month_name, '%B').month
print(month_num, type(month_num))
>> 1 <class 'int'>
部分月份名称到月份编号(例如 Jan、Feb 等):
import datetime
month_name = 'Feb'
month_num = datetime.datetime.strptime(month_name, '%b').month
print(month_num, type(month_num))
>> 2 <class 'int'>
您还可以将其格式化为两位数表示形式:
month_num = 3
formatted = f"{month_num:02}"
print(formatted, type(formatted))
>> 03 <class 'str'>
月份编号到完整的月份名称(无论是否为两位数,字符串或整数)(例如 '01'、1 等):
import datetime
month_num = '04' # month_num = 4 will work too
month_name = datetime.datetime(1, int(month_num), 1).strftime("%B")
print(month_name)
>> April
月份编号到部分月份名称(无论是否为两位数,字符串或整数)(例如'01',1等):
import datetime
month_num = 5 # month_num = '05' will work too
month_name = datetime.datetime(1, int(month_num), 1).strftime("%b")
print(month_name)
>> May
要从月份编号获取完整的日历名称,您可以使用calendar.month_name。请参阅文档了解更多详细信息:https://docs.python.org/2/library/calendar.html
month_no = 1
month = calendar.month_name[month_no]
# month provides "January":
print(month)
form month name to number
d=['JAN','FEB','MAR','April','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']
N=input()
for i in range(len(d)):
if d[i] == N:
month=(i+1)
print(month)
您可以尝试:
pd.to_datetime(df['month'], format='%b').dt.month
>>> calendar.month_abbr[:].index('Jan')
1
基于上述想法,这对于将月份名称更改为适当的月份编号非常有效:
from time import strptime
monthWord = 'september'
newWord = monthWord [0].upper() + monthWord [1:3].lower()
# converted to "Sep"
print(strptime(newWord,'%b').tm_mon)
# "Sep" converted to "9" by strptime
您可以使用以下作为替代方案。
from time import strptime
strptime('Feb','%b').tm_mon
import calendar
calendar.month_abbr[2]
或
calendar.month[2]
def month_num2abbr(month):
month = int(month)
import calendar
months_abbr = {month: index for index, month in enumerate(calendar.month_abbr) if month}
for abbr, month_num in months_abbr.items():
if month_num==month:
return abbr
return False
print(month_num2abbr(7))
如果您不想导入日历库,并且需要更强大的东西 - 您可以使您的代码比提供的其他一些解决方案更动态一些对于不一致的文本输入。你可以:
month_to_number
字典.items()
并检查字符串 s
的小写字母是否在小写键 k
中。month_to_number = {
'January' : 1,
'February' : 2,
'March' : 3,
'April' : 4,
'May' : 5,
'June' : 6,
'July' : 7,
'August' : 8,
'September' : 9,
'October' : 10,
'November' : 11,
'December' : 12}
s = 'jun'
[v for k, v in month_to_number.items() if s.lower() in k.lower()][0]
Out[1]: 6
同样,如果您有一个列表
l
而不是字符串,则可以添加另一个 for
来循环列表。我创建的列表具有不一致的值,但输出仍然是正确的月份数字所需的:
l = ['January', 'february', 'mar', 'Apr', 'MAY', 'JUne', 'july']
[v for k, v in month_to_number.items() for m in l if m.lower() in k.lower()]
Out[2]: [1, 2, 3, 4, 5, 6, 7]
我这里的用例是,我使用
Selenium
通过根据某些条件自动选择下拉值来从网站上抓取数据。不管怎样,这需要我依赖一些我相信我们的供应商每月手动输入标题的数据,如果他们的格式与历史上的格式略有不同,我不想回到我的代码。