将年、月、日的单独系列转换为单个日期时间系列



我有Pandas系列的年份、月份和日期:

year = [2016]
months = [6,7]
days = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

它们来自同一个Dataframe,因此索引匹配。例如,2016、6、1比赛的索引,以及7和第二天系列赛的第1个索引。

如何将其转换/组合为一个单独的序列作为日期时间?

比如

date = [2016-06-01, 2016-06-03, ..., 2016-06-30, 2016-07-01]

由于日子都在一个系列中,我很难将它们分开几个月。

从您的数据开始:

years = [2016]
months = [6,7]
days = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

解决方案1

我们可以这样做:

import pandas as pd
from datetime import datetime

def date_cleanup(days, months, years):
res = []
last_day = 0
cmp = 0
for year in years:
for month in months:
for day in days:
if day > last_day:
res.append(datetime(year, month, day))
cmp += 1
last_day = day
else:
last_day = 0
days = days[cmp:]
break
return pd.Series(res)

我们在这里做的是yearsmonthsdays上的多循环。当我们得到比前一天小的一天时,我们从days的列表中删除所有已经使用的元素,并通过for循环更改月份
您将得到预期结果:

>>> date_cleanup(days, months, years)
0    2016-06-01
1    2016-06-03
2    2016-06-04
3    2016-06-05
4    2016-06-06
5    2016-06-07
6    2016-06-08
7    2016-06-09
8    2016-06-10
9    2016-06-11
10   2016-06-12
11   2016-06-29
12   2016-06-30
13   2016-07-01
14   2016-07-02
15   2016-07-03
16   2016-07-04
17   2016-07-05
18   2016-07-07
19   2016-07-12
20   2016-07-13
21   2016-07-14
22   2016-07-15
23   2016-07-16
24   2016-07-17
25   2016-07-18
26   2016-07-19
27   2016-07-20
28   2016-07-21
29   2016-07-22
30   2016-07-23
31   2016-07-24
32   2016-07-25
33   2016-07-26
34   2016-07-27
35   2016-07-28
36   2016-07-29
37   2016-07-30
dtype: datetime64[ns]

解决方案2

感谢@Vishnudev的评论,我推送了答案,以获得基于Pandas和Numpy的更优雅的解决方案:

>>> years = [2006]
>>> months = [6, 7]
>>> days = [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
>>> df = pd.DataFrame(days, columns=['day'])

我们使用diff方法找到变化的月份,并使用布尔值标记diff为负的时间(例如从30到1(。然后,我们在此列上应用cumsum以与months的列表的索引相匹配。

>>> df['switch'] = np.where((df['day'].diff()>0) | (df['day'].diff().isna()), 0, 1)
>>> df['indice'] = df['switch'].cumsum()
>>> df['month'] = [months[i] for i in df['indice'].tolist()]
>>> df
day   switch  indice  month
0   1   0       0       6
1   3   0       0       6
2   4   0       0       6
3   5   0       0       6
4   6   0       0       6
5   7   0       0       6
6   8   0       0       6
7   9   0       0       6
8   10  0       0       6
9   11  0       0       6
10  12  0       0       6
11  29  0       0       6
12  30  0       0       6
13  1   1       1       7
14  2   0       1       7
15  3   0       1       7
16  4   0       1       7
17  5   0       1       7
18  7   0       1       7
19  12  0       1       7
20  13  0       1       7
21  14  0       1       7
22  15  0       1       7
23  16  0       1       7
24  17  0       1       7
25  18  0       1       7
26  19  0       1       7
27  20  0       1       7
28  21  0       1       7
29  22  0       1       7
30  23  0       1       7
31  24  0       1       7
32  25  0       1       7
33  26  0       1       7
34  27  0       1       7
35  28  0       1       7
36  29  0       1       7
37  30  0       1       7

现在,我们从years列表中添加年份,并删除不必要的列,我们得到了预期的结果:

>>> df['year'] = years[0]
>>> df.drop(['switch', 'indice'], axis=1)
>>> df
day month   year
0   1   6       2006
1   3   6       2006
2   4   6       2006
3   5   6       2006
4   6   6       2006
5   7   6       2006
6   8   6       2006
7   9   6       2006
8   10  6       2006
9   11  6       2006
10  12  6       2006
11  29  6       2006
12  30  6       2006
13  1   7       2006
14  2   7       2006
15  3   7       2006
16  4   7       2006
17  5   7       2006
18  7   7       2006
19  12  7       2006
20  13  7       2006
21  14  7       2006
22  15  7       2006
23  16  7       2006
24  17  7       2006
25  18  7       2006
26  19  7       2006
27  20  7       2006
28  21  7       2006
29  22  7       2006
30  23  7       2006
31  24  7       2006
32  25  7       2006
33  26  7       2006
34  27  7       2006
35  28  7       2006
36  29  7       2006
37  30  7       2006

更新

正如您在评论@donnyan中所指出的,您能够提供一组相同长度的数据,我们可以按照@HenryEcker和@Vishnudev的建议,使用Pandas的力量,直接使用@Henry埃克解决方案:

pd.to_datetime(pd.DataFrame({'year': years, 'month': months, 'day': days})

最新更新