我有一个pandas数据框,其中一个名为period的列有3个不同的标签值,表示2019年冬季,2020年冬季和2021年冬季,如下图所示
我的问题是如何替换这种格式,最终结果是2019年冬季,2020年冬季和冬季2021年?
Period:
Q4 '19+Q1 '20
Q4 '20+Q1 '21
Q4 '21+Q1 '22
Q表示一年中的四分之一
所以我的方法是:1)首先是制作新年专栏的正则表达式方法。我在第一个Q4之后提取了'19,',20,'21年的数字
gas['year'] = gas['Period'].str.extract("([']\d\d)", expand=True)
然后我打算用冬天替换含有Q4和Q1的值
gas['Period'].str.contains('Q4')) & (gas['Period'].str.contains('Q1')) = 'winter Gregorian'
但它取代了包含Q4和Q1的整行
也试过了
gas[gas['Period'].str.replace("[Q][4]..\d\d[+][Q][1]", 'winter Gregorian'), regex =False]
最终结果我想要的东西:
Period
winter Gregorian 2019
winter Gregorian 2020
winter Gregorian 2021
但没有工作,我欢迎任何意见和建议,谢谢
我会在这里使用regex capture groups。看看这个正则表达式:
(Q[0-9]) '([0-9]{2})\+(Q[0-9]) '([0-9]{2})
括号中的每个项目都是您在匹配后可以访问的组。例如,在Q4 '19+Q1 '20
中,比赛中的第一组是Q4
,第二组是19
,第三组是Q1
,第四组是20
。
将Period字符串与此正则表达式匹配后,您可以拉出组匹配以构建所需的输出格式。此代码为您提供了如何执行此操作的完整示例。
import re
import pandas as pd
df = pd.DataFrame({
"Period": [
"Q4 '19+Q1 '20 ",
"Q1 '20+Q2 '20",
"Q4 '20+Q1 '21",
"Q4 '21+Q1 '22"
]
})
pattern = "(Q[0-9]) '([0-9]{2})\+(Q[0-9]) '([0-9]{2})"
season_map = {
('Q4', 'Q1'): 'Winter',
('Q1', 'Q2'): 'Spring',
('Q2', 'Q3'): 'Summer',
('Q3', 'Q4'): 'Fall'
}
def convert_time_format(x):
match = re.match(pattern, x)
if match is not None:
season = season_map.get((match.group(1), match.group(3)))
year = match.group(2)
return season + ' ' + year
else:
return 'Failed to parse'
df.Period.map(convert_time_format)
这给了:
0 Winter 19
1 Spring 20
2 Winter 20
3 Winter 21
所以我生成我自己的版本以查找所有月份并格式化它们并获得:TypeError:不支持的操作数类型+:'NoneType'和'str'
pattern3 = "(\w+) '([0-9]{2})"
month_map = {
('January'): 'Jan',
('February'): 'Feb',
('March'): 'Mar',
('April'): 'Apr',
('June'): 'Jun',
('July'): 'Jul',
('August'): 'Aug',
('September'): 'Sep',
('October'): 'Oct',
('November'): 'Nov',
('December'): 'Dec',
}
def convert_month(x):
match = re.match(pattern3, x)
if match is not None:
month = month_map.get((match.group(1)))
year = '20'+match.group(2)
return month + '_' + year
else:
return x
gas['Period'] = gas.Period.map(convert_month)
抱歉,卢克可能不得不再次打扰你