将 pandas 列从字符串 Quarters 和 Years 数组转换为 datetime 列

Posted

技术标签:

【中文标题】将 pandas 列从字符串 Quarters 和 Years 数组转换为 datetime 列【英文标题】:Converting a pandas column from an array of string Quarters and Years to a datetime column 【发布时间】:2021-06-01 20:28:23 【问题描述】:

我有以下数据框

        Date        Data
0   [Q1, 10]         8.7
1   [Q2, 10]         8.4
2   [Q3, 10]        14.1
3   [Q4, 10]        16.2
4   [Q1, 11]        18.6
5   [Q2, 11]        20.4
6   [Q3, 11]        17.1
7   [Q4, 11]        37.0
8   [Q1, 12]        35.1
9   [Q2, 12]        26.0
10  [Q3, 12]        26.9
11  [Q4, 12]        47.8
12  [Q1, 13]        37.4
13  [Q2, 13]        31.2
14  [Q3, 13]        33.8
15  [Q4, 13]        51.0
16  [Q1, 14]        43.7
17  [Q2, 14]        35.2
18  [Q3, 14]        39.3
19  [Q4, 14]        74.5
20  [Q1, 15]        61.2
21  [Q2, 15]        47.5
22  [Q3, 15]        48.0
23  [Q4, 15]        74.8
24  [Q1, 16]        51.2
25  [Q2, 16]        40.4
26  [Q3, 16]        45.5
27  [Q4, 16]        78.3
28  [Q1, 17]        50.8
29  [Q2, 17]        38.5
30  [Q3, 17]        46.7
31  [Q4, 17]        77.3
32  [Q1, 18]        52.2
33  [Q2, 18]        41.3
34  [Q3, 18]        46.9
35  [Q4, 18]        68.4
36  [Q1, 19]        36.4
37  [Q2, 19]        33.8
38  [Q3, 19]        46.6
39  [Q4, 19]        73.8
40  [Q1, 20]        36.7
41  [Q2, 20]        37.6

我想将它合并到一个Date 到一个 Datetime 对象中,

所以Q1,10会变成Q1,2010然后变成2010-03-31

我尝试了以下代码,

df['Date'] = pd.to_datetime(df['Date'].str.join('20'))

但它不起作用。

我也尝试过使用

df['Date'].astype(str)[:1]

访问系列中的第二列以在前面添加 20,但它不会让我。

将此系列转换为 pandas 数据时间列的最佳方法是什么?

【问题讨论】:

日期列有列表或字符串? 它是一个字符串数组 【参考方案1】:

首先创建季度PeriodIndex,然后通过PeriodIndex.to_timestamp 转换为日期时间,并通过DatetimeIndex.floor 转换为天数:

#if necessary create lists
df['Date'] = df['Date'].str.strip('[]').str.split(',')

#test if format match
print ('20' + df['Date'].str[::-1].str.join(''))
0    2010Q1
1    2010Q2
2    2010Q3
3    2010Q4
4    2011Q1
5    2011Q2
Name: Date, dtype: object


df['Date'] = (pd.PeriodIndex('20' + df['Date'].str[::-1].str.join(''), freq='Q')
                .to_timestamp(how='e')
                .floor('d'))
print (df)
        Date  Data
0 2010-03-31   8.7
1 2010-06-30   8.4
2 2010-09-30  14.1
3 2010-12-31  16.2
4 2011-03-31  18.6
5 2011-06-30  20.4

转换为Periods 的替代方案:

df['Date'] = (df['Date'].str[::-1].str.join('').apply(lambda x: pd.Period(x, freq='Q'))
                    .dt.to_timestamp(how='e')
                    .dt.floor('d'))

或来自@MrFuppes 的解决方案,谢谢:

df['Date'] = (pd.to_datetime("20"+df['Date'].str[::-1].str.join('')) + 
              pd.offsets.QuarterEnd(0))

【讨论】:

我收到一个错误TypeError: Incorrect dtype 是不是因为它的 Q1 而不是 1Q 现在我得到了AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas,也许它是我的熊猫版本,我刚刚更新了它,你用的是什么版本 @anarchy - 我用pandas : 1.2.1 我的格式在第二部分完全匹配你的,我只是无法到达最后一个命令

以上是关于将 pandas 列从字符串 Quarters 和 Years 数组转换为 datetime 列的主要内容,如果未能解决你的问题,请参考以下文章

将 pandas 数据框列从十六进制字符串转换为 int

Pandas 基于连接将列从一个数据帧添加到另一个数据帧

Pandas - 将日期列从 dd/mm/yy hh:mm:ss 转换为 yyyy-mm-dd hh:mm:ss

Pandas 映射到 TRUE/FALSE 作为字符串,而不是布尔值

根据另一列从 Pandas 系列中的列表中选择元素

如何向 pandas df 添加一个新列,该列从另一个数据帧返回同一组中更大的最小值