微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python和熊猫:Timedelta系列

M是数据帧df中的col,它指示月份数.

M
1
0
15

我想找出2015年1月1日至2015年1月1日df.M之间的天数.以下col是我想要的.

daynum
31
0
456

我知道如何使用循环和列表来做到这一点:

int((datetime.strptime("2015-01-01", "%Y-%m-%d") + relativedelta(months=df.M[i]) 
                    - datetime.strptime("2015-01-01", "%Y-%m-%d")).days)

大熊猫中是否有任何内置函数可以轻松解决此问题?

解决方法:

您可以使用与问题中相同的方法,但是使用自动矢量化操作而不是循环.
首先将整数系列转换为relativedelta

In [76]: M = pd.Series([1, 0, 15])

In [77]: M2 = M.apply(lambda x: dateutil.relativedelta.relativedelta(months=x))

In [78]: M2
Out[78]:
0              relativedelta(months=+1)
1                       relativedelta()
2    relativedelta(years=+1, months=+3)
dtype: object

然后,您可以执行相同的计算:

In [80]: (pd.Timestamp('2015-01-01') + M2) - pd.Timestamp('2015-01-01')
Out[80]:
0    31 days
1     0 days
2   456 days
dtype: timedelta64[ns]

如果您希望将其作为整数值而不是上面的timedelta,则可以使用.dt.days来获得它:

In [81]: days = (pd.Timestamp('2015-01-01') + M2) - pd.Timestamp('2015-01-01')

In [82]: days.dt.days
Out[82]:
0     31
1      0
2    456
dtype: int64

不使用timedelta的原因

在这种情况下,您将无法使用时间增量,因为这不能将日期精确地偏移一定的月份数,但是它似乎为您提供了某种平均月份长度:

In [83]: pd.to_timedelta(1, unit='M')
Out[83]: timedelta('30 days 10:29:06')

In [84]: (pd.Timestamp('2015-01-01') + pd.to_timedelta(M, unit='M')) - pd.Timestamp('2015-01-01')
Out[84]:
0    30 days 10:29:06
1     0 days 00:00:00
2   456 days 13:16:30
dtype: timedelta64[ns]

因此,这将给出稍微不同的答案.例如,在这种情况下,第一个元素为您提供30天而不是31天.

相当于relativedelta的熊猫将使用DateOffset.在这种情况下,例如pd.DateOffset(months = 1)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐