在pandas的datetime列中添加月份

2024-05-15 10:01:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框df,有两列如下-

               START_DATE             MONTHS
0              2015-03-21                240
1              2015-03-21                240
2              2015-03-21                240
3              2015-03-21                240
4              2015-03-21                240
5              2015-01-01                120
6              2017-01-01                240
7                     NaN                NaN
8                     NaN                NaN
9                     NaN                NaN

这两列的数据类型是对象。

>>> df.dtypes
START_DATE    object
MONTHS        object
dtype: object

现在,我想通过添加df['START_DATE']&df['MONTHS']来创建一个新的列“Result”。所以,我已经做了以下工作-

from dateutil.relativedelta import relativedelta  

df['START_DATE'] = pd.to_datetime(df['START_DATE'])
df['MONTHS'] = df['MONTHS'].astype(float)

df['offset'] = df['MONTHS'].apply(lambda x: relativedelta(months=x))

df['Result'] = df['START_DATE'] + df['offset'] 

这里,我得到以下错误-

TypeError: incompatible type [object] for a datetime/timedelta operation

注意:希望将df['Months']转换为int,但由于字段有空,因此无法工作。

你能给我指路吗?谢谢。


Tags: 数据对象dfdatetimedateobjectresultnan
3条回答

这是一种矢量化的方法,所以应该非常有表现力。请注意,它不处理月交叉/结束(也不处理DST更改)。我相信这就是为什么你得到了《泰晤士报》。

In [32]: df['START_DATE'] + df['MONTHS'].values.astype("timedelta64[M]")
Out[32]: 
0   2035-03-20 20:24:00
1   2035-03-20 20:24:00
2   2035-03-20 20:24:00
3   2035-03-20 20:24:00
4   2035-03-20 20:24:00
5   2024-12-31 10:12:00
6   2036-12-31 20:24:00
7                   NaT
8                   NaT
9                   NaT
Name: START_DATE, dtype: datetime64[ns]

如果您需要精确的MonthEnd/Begin处理,这是一种合适的方法。(使用MonthsOffset获得同一天)

In [33]: df.dropna().apply(lambda x: x['START_DATE'] + pd.offsets.MonthEnd(x['MONTHS']), axis=1)
Out[33]: 
0   2035-02-28
1   2035-02-28
2   2035-02-28
3   2035-02-28
4   2035-02-28
5   2024-12-31
6   2036-12-31
dtype: datetime64[ns]

这里有一种不需要dateutil.relativedelta的方法。请注意,我将MONTHS转换为一个整数(并且仅在删除空值之后,因为int不接受空值),因为我想每年进行12个月的整数除法,利用商是以年为单位的增量,模/余数是以月为单位的增量。

import pandas as pd

df = pd.DataFrame({'START_DATE':['2015-03-21','2015-03-21','2015-03-21','2015-03-21',
                                 '2015-03-21','2015-01-01','2017-01-01', None,None,None],
                   'MONTHS':[240,240,240,240,240,120,240,None,None,None]},
                  dtype='object') # replicate example data

df.dropna(inplace=True) # drop nulls so can convert MONTHS to int
df['START_DATE'] = pd.to_datetime(df['START_DATE'])
df['MONTHS'] = df.MONTHS.astype(int)

df.apply(lambda x: pd.datetime(x.START_DATE.year + x.MONTHS / 12,
                               x.START_DATE.month + x.MONTHS % 12,
                               x.START_DATE.day), axis=1)

如果数据帧很小,请使用以下命令。我使用了axis=1,这是行操作。如果你的数据帧很大,速度会很慢

> df['offset'] = df.dropna().apply(lambda v: relativedelta(months=int(v['MONTHS'])) + v['START_DATE'], axis=1)
> df
  START_DATE  MONTHS     offset
0 2015-03-21     240 2035-03-21
1 2015-03-21     240 2035-03-21
2 2015-03-21     240 2035-03-21
3 2015-03-21     240 2035-03-21
4 2015-03-21     240 2035-03-21
5 2015-01-01     120 2025-01-01
6 2017-01-01     240 2037-01-01
7        NaT     NaN        NaT
8        NaT     NaN        NaT
9        NaT     NaN        NaT

相关问题 更多 >