一种将熊猫的季度时间转换为日期时间的干净方法

时间:2018-12-22 18:56:44

标签: python pandas date datetime period

我正在寻找一种很好的,易于理解的方式(您下次可以记住的一种方式)将“ 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

我希望以下内容能起作用,因为它可读性强,但不幸的是,它不起作用:

df['date'] = pd.to_datetime(df['Quarter'], format='%q %Y')

问题还在于,季和年显然对大熊猫进行简单处理的顺序错误。

有人可以帮助我找到一种更清洁的方法,将“ 1996年第三季度”转换为熊猫的日期时间吗?

3 个答案:

答案 0 :(得分:3)

您可以(并且应该)使用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

因为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

如果性能很重要,则可以拆分和合并,但可以做到干净整洁:

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

答案 1 :(得分:2)

对前四个2使用最后4个值进行切片,并将其转换为日期时间:

df['date'] = pd.to_datetime(df['Quarter'].str[-4:] + df['Quarter'].str[:2])

熊猫中的字符串操作速度很慢,因此,如果不可能缺少任何值,请使用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

答案 2 :(得分:1)

鉴于2018-Q1这样的四分之一格式,可以使用内置的pd.to_datetime函数。一般而言,答案是必须处理许多种可以存储四分之一年观测值的方法(例如2018:12018:Q120181Q1:2018等) ,将数据强制为 supra 格式超出了我的答案范围。

但是给定一个格式化的系列:

formatted_series = formatted_series_supplier() ...
df['date'] = pd.to_datetime(formatted_series)

如果您要处理的监管数据几乎总是反映季度末而不是季度开始(例如,您要使用2019-03-31而不是2019-01-01),则可以使用类似下方:

df['date'] = df['date'] + pd.offsets.QuarterEnd(0)
相关问题