我有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)
我们在这里做的是years
、months
和days
上的多循环。当我们得到比前一天小的一天时,我们从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})