我有一个名为weather的数据集,它包含一列"Date",如下所示。
| 日期|
| - ------|
| 2020年1月1日|
| 2020年1月2日|
| 2020年2月1日|
| 2020年2月4日|
| 2020年3月1日|
| 2020年4月1日|
| 2020年4月2日|
| 2020年4月3日|
| 2020年4月4日|
| 2020年5月1日|
| 2020年6月1日|
| 2020年7月1日|
| 2020年8月1日|
| 2020年9月1日|
| 2020年10月1日|
| 2020年11月1日|
| 2020年1月1日|
| 2020年2月1日|
| 2020年4月1日|
| 2020年5月1日|
| 2020年6月1日|
| 2020年7月1日|
| 2020年8月1日|
| 2020年9月1日|
| 2020年10月1日|
| 2020年11月1日|
| 2020年12月1日|
| 2020年1月1日|
问题是,应该是2020年、2021年和2022年的年份总是2020年。
所需的列如下所示
| 日期|
| - ------|
| 2020年1月1日|
| 2020年1月2日|
| 2020年2月1日|
| 2020年2月4日|
| 2020年3月1日|
| 2020年4月1日|
| 2020年4月2日|
| 2020年4月3日|
| 2020年4月4日|
| 2020年5月1日|
| 2020年6月1日|
| 2020年7月1日|
| 2020年8月1日|
| 2020年9月1日|
| 2020年10月1日|
| 2020年11月1日|
| 2021年1月1日|
| 二○二一年二月一日|
| 二○二一年四月一日|
| 二○二一年五月一日|
| 二○二一年六月一日|
| 2021年7月1日|
| 2021年8月1日|
| 2021年9月1日|
| 二○二一年十月一日|
| 二○二一年十一月一日|
| 二○二一年十二月一日|
| 2022年1月1日|
每年的最后一个月不一定是12日,但新的一年从01月开始。
下面是我的代码:
month = ['01','02','03','04','05','06','07','08','09','10','11','12']
for i in range(len(weather['Date'])):
year = 2022
for j in range(len(month)):
if weather['Date'][i][5:7] == '01':
weather['Date'][i] = weather['Date'][i].apply(lambda x: 'year' + x[5:])
有什么建议可以修复我的代码并获得所需的列吗?
2条答案
按热度按时间9rygscc11#
这里有一个方法:
pd.to_datetime
并应用Series.diff
和chainSeries.dt.day
,将Date
列中的日期字符串转换为datetime。Series
中的每个 * 负 * 值(即"day")都表示新的一年的开始,因此我们应用Series.lt(0)
将所有低于0
的值转换为True
,其余值转换为False
。Series.cumsum
链接起来,最终得到一个包含0, ..., 1, ..., 2
的Series
,这些值需要添加到年份2020
中,以获得正确的年份。(new_year = year + addition), month, day
再次传递给pd.to_datetime
来创建正确的日期了(参见SO answer)。当然,转换成datetime并不需要 *,也可以重新创建日期字符串,去掉下面这行:
osh3o9ms2#
类似于@ouroboros1,但是使用
numpy
来获得要添加到每个日期的年数,然后使用pd.offsets.DateOffset(years=...)
来进行添加。在这一点上,很容易做到:
但我们会得到警告:
PerformanceWarning: Adding/subtracting object-dtype array to DatetimeArray not vectorized.
因此,我们改为按要添加的年数分组,并将相关偏移添加到组中的所有日期。
这是相当快的(4.25毫秒对于1000行和10个不同的
y
值),并且,对于其他情况,比@ouroboros1的答案更一般:1.它处理由于闰年引起的日期更改(在您的示例中没有出现,因为所有日期都是一个月的第一天,但是如果其中一个日期是'2020-02-29',并且我们尝试使用构造
dt = df['Date'].dt; pd.to_datetime(dict(year=dt.year + y, month=dt.month, ...)
向其添加1年,则会得到ValueError: cannot assemble the datetimes: day is out of range for month
)。1.它保留一天中的任何时间和时区信息(同样,不是在您的情况下,但在一般情况下,人们会保留这些信息)。