San*_*ord 3 python datetime date period pandas
我正在寻找一种很好的,易于理解的方式(您下次可以记住的一种方式)将“ Q3 1996”转换为熊猫的日期时间,例如本例中的“ 1996-07-01”。到目前为止,我发现了这一点,但它非常丑陋:
df = pd.DataFrame({'Quarter':['Q3 1996', 'Q4 1996', 'Q1 1997']})
?
df['date'] = (
pd.to_datetime(
df['Quarter'].str.split(' ').apply(lambda x: ''.join(x[::-1]))
))
?
print(df)
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
Run Code Online (Sandbox Code Playgroud)
我希望以下内容可以工作,因为它可读性强,但不幸的是它不行:
df['date'] = pd.to_datetime(df['Quarter'], format='%q %Y')
Run Code Online (Sandbox Code Playgroud)
问题还在于,季度和年份显然对大熊猫进行简单处理的顺序错误。
谁能帮我找到一种更清洁的方法,将“ 1996年第三季度”转换为大熊猫日期时间?
使用第一个按最后 4 个值进行切片2并转换为日期时间:
df['date'] = pd.to_datetime(df['Quarter'].str[-4:] + df['Quarter'].str[:2])
Run Code Online (Sandbox Code Playgroud)
pandas 中的字符串操作很慢,所以如果没有缺失值是可能的,请使用list comprehension:
#python 3.6+
df['date'] = pd.to_datetime([f'{x[-4:]}{x[:2]}' for x in df['Quarter']])
#python bellow
#df['date'] = pd.to_datetime(['{}{}'.format(x[-4:], x[:2]) for x in df['Quarter']])
print (df)
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
Run Code Online (Sandbox Code Playgroud)
您可以(并且应该)pd.PeriodIndex用作第一步,然后使用转换为时间戳PeriodIndex.to_timestamp:
qs = df['Quarter'].str.replace(r'(Q\d) (\d+)', r'\2-\1')
qs
0 1996-Q3
1 1996-Q4
2 1997-Q1
Name: Quarter, dtype: object
df['date'] = pd.PeriodIndex(qs, freq='Q').to_timestamp()
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
Run Code Online (Sandbox Code Playgroud)
初始替换步骤是必要的,因为PeriodIndex您期望使用%Y-%q格式的期间。
另一种选择是pd.to_datetime在执行字符串替换之后以与以前相同的方式使用。
df['date'] = pd.to_datetime(
df['Quarter'].str.replace(r'(Q\d) (\d+)', r'\2-\1'), errors='coerce')
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
Run Code Online (Sandbox Code Playgroud)
如果性能很重要,则可以拆分并合并,但是可以干净地进行:
df['date'] = pd.to_datetime([
'-'.join(x.split()[::-1]) for x in df['Quarter']])
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
Run Code Online (Sandbox Code Playgroud)
给定四分之一格式,例如2018-Q1,可以使用内置pd.to_datetime函数。
作为一般的回答将不得不应对的方法之一可存储的四分之一年的观察(如多如牛毛2018:1,2018:Q1,20181,Q1:2018,等),强迫将数据导入格式超是我的回答的范围之外。
但给定一个格式化的系列:
formatted_series = formatted_series_supplier() ...
df['date'] = pd.to_datetime(formatted_series)
Run Code Online (Sandbox Code Playgroud)
如果您正在处理监管数据,这些数据几乎总是反映季度末而不是开始(即,您想要 2019-01-01,而不是 2019-03-31),您可以使用如下抵消:
df['date'] = df['date'] + pd.offsets.QuarterEnd(0)
Run Code Online (Sandbox Code Playgroud)