Python Pandas:如何应用需要扩展类(datetime)的函数?

3

如何在需要扩展标准类(datetime)的函数中使用 pandas 的 apply

具体而言,我想从 https://gist.github.com/treyhunner/6218526 导入 datetime_modulo

该代码扩展了标准的 datetime 类,使得可以对 datetime 对象应用模数运算,例如:

from datetime_modulo import datetime
from datetime import timedelta
d = datetime.now()
print d % timedelta(seconds=60)

现在我需要将这个模数操作应用到 pandas DataFrame 的列/序列上,例如: apply
df['dates'] = pd.to_datetime(df.index.values)
df['datetime_mod'] = df['dates'].apply(lambda x: x % timedelta(minutes=15))

但是pandas无法检测到扩展的日期时间类(除非我使用不当):

TypeError: unsupported operand type(s) for %: 'Timestamp' and 'datetime.timedelta'

如何继续?
3个回答

3

您可以尝试按照此建议将操作数明确转换为datetime:

from datetime_modulo import datetime
from datetime import timedelta

df = pd.DataFrame({'Time': [pd.to_datetime('now')]})

def modulo(x):
    dt = datetime(year=x.year,month=x.month,day=x.day, hour=x.hour, minute=x.minute, second=x.second)
    return dt % timedelta(seconds=60)

df['Time'] = df['Time'].apply(modulo)

优秀的答案 <占位符> - Ami Tavory
1
@AmiTavory,你的代码也很棒 +1 :)。我的代码可能有些繁琐,但更通用,可以处理(例如)天/分钟/秒的模数。 - jpp
@jpp 太棒了,谢谢,可以用!我稍微修改了timedelta的参数(并将其更改为datetime),并且已经编辑了您的答案 - 这样可以吗? - jtlz2
@jtlz2,没问题。 - jpp

3
一般来说,在Pandas中,应尽量避免调用apply,因为它速度非常慢。例如,如果您想查找每个小时刻度内的分钟数,可以使用以下代码:
from datetime import timedelta
df = pd.DataFrame({'dates': pd.to_datetime(['2071-12-12 10:04:44', '2071-12-12 10:30:44'])})
>>> df.dates.dt.minute.mod(15)
0    4
1    0
Name: dates, dtype: int64

谢谢您 - 实际上行数很少,问题确实涉及到了apply。非常感谢! - jtlz2

2
你是对的,只是使用方法不正确。
看到这个错误:TypeError: unsupported operand type(s) for %: 'Timestamp' and 'datetime.timedelta'
这个错误意味着你不能简单地写x % timedelta(minutes=15)并希望它能工作。它不行。xTimestamp的一个实例,不知道如何用%来操作datetime.timedelta。如果你想让它工作,你至少需要将x转换为datetime_modulo.datetime

好的答案 <填充语>. - Ami Tavory
lambda x: datetime(x) % timedelta(minutes=15) - jtlz2
@Sraw,提议的解决方案在哪里? - jtlz2

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