M 是 dataframe df 中的一个列,表示月数。
M
1
0
15
我正在尝试查找 2015-01-01 和 2015-01-01 + 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)
pandas有没有内置函数可以轻松解决这个问题?
最佳答案
您可以使用与问题中相同的方法,但使用自动矢量化操作而不是循环。
首先将整数系列转换为 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
的原因
在这种情况下,您不能使用 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
的 pandas 将使用 DateOffset
。在这种情况下,例如 pd.DateOffset(months=1)
关于 python 和 Pandas : series to timedelta,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35233251/