使用日期进行pandas数据帧的列算术运算

6

我认为这应该很容易,但我遇到了一些困难。我有一个数据集,从Stata .dta文件导入到pandas dataframe中。几列包含日期数据。dataframe包含100,000多行,但给出了一个样本:

   cat  event_date  total
0   G2  2006-03-08     16
1   G2         NaT    NaN
2   G2         NaT    NaN
3   G3  2006-03-10     16
4   G3  2006-08-04     12
5   G3  2006-12-28     13
6   G3  2007-05-25     10
7   G4  2006-03-10     13
8   G4  2006-08-06     19
9   G4  2006-12-30     16

数据存储为datetime64格式:
>>> mydata[['cat','event_date','total']].dtypes
cat                    object
event_date     datetime64[ns]
total                 float64
dtype: object

我要做的就是创建一个新列,该列给出事件日期和开始日期(例如2006-01-01)之间的天数差异(而不是'us'或'ns'!)。 我尝试了以下方法:

>>> mydata['new'] = mydata['event_date'] - np.datetime64('2006-01-01')

...但是我收到了这个消息:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

我也尝试了使用 lambda 函数,但它也不起作用。

然而,如果我只想在每个日期上添加一天,我可以成功地使用:

>>> mydata['plusone'] = mydata['event_date'] + np.timedelta64(1,'D')

那很好。

我有什么简单的东西漏掉了吗?

提前感谢任何帮助。


你的问题很奇怪,我无法解释,但以下方法对我有效:import datetime as dt mydata['new'] = mydata['event_date'] - dt.datetime(2006,1,1) 你能确认一下吗? - EdChum
1
我工作时尽量避免直接使用“np.datetime64”,但是这是一个错误:https://github.com/pydata/pandas/issues/7996 - Jeff
2个回答

6

不确定为什么 numpy 的 datetime64 与 pandas 的数据类型不兼容,但使用 datetime 对象对我来说可以正常工作:

In [39]:

import datetime as dt
mydata['new'] = mydata['event_date'] - dt.datetime(2006,1,1)
mydata
Out[39]:
      cat event_date  total      new
Index                               
0      G2 2006-03-08     16  66 days
1      G2        NaT    NaN      NaT
2      G2        NaT    NaN      NaT
3      G3 2006-03-10     16  68 days
4      G3 2006-08-04     12 215 days
5      G3 2006-12-28     13 361 days
6      G3 2007-05-25     10 509 days
7      G4 2006-03-10     13  68 days
8      G4 2006-08-06     19 217 days
9      G4 2006-12-30     16 363 days

完美地运作 - 非常感谢!但我仍然有点困惑 - 当日期和时间信息以datetime64的形式存储在pandas数据框中时,这不是numpy格式吗?如果是这样,为什么datetime可以工作而datetime64不能? - user1718097
@user1718097 这就是让我困惑的地方,我没有答案,希望Pandas开发人员中的某个人可以发表评论。 - EdChum
刚看到Jeff的评论,这是一个bug,在未来的版本中应该会得到修复,你也可以点赞;) - EdChum
@user1718097 最好直接将错误提交到https://github.com/pydata/pandas/issues,而不是在这里在SO上发布,如果你知道它是一个错误的话,有时候很难判断。 - EdChum

2

确保你有最新版本的pandas和numpy(>=1.7):

In [11]: df.event_date - pd.Timestamp('2006-01-01')
Out[11]:
0    66 days
1        NaT
2        NaT
3    68 days
4   215 days
5   361 days
6   509 days
7    68 days
8   217 days
9   363 days
Name: event_date, dtype: timedelta64[ns]

谢谢提供的信息 - 完美运作。几乎在同一时间,有一个非常相似的解决方案使用了dt.datetime()而不是pd.Timestamp()。我将那个答案标记为已接受,仅仅是因为我过去更频繁地使用datetime()。但这个解决方案同样有效。 - user1718097

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接