【问题标题】:How to remove microseconds from timedelta如何从 timedelta 中删除微秒
【发布时间】:2017-09-13 18:10:40
【问题描述】:

我想从 pandas 列中截断几微秒。我尝试了analyze_me['how_long_it_took_to_order'] = analyze_me['how_long_it_took_to_order'].apply(lambda x: x.replace(microsecond=0) 之类的方法,但出现了这个错误replace() takes no keyword arguments

例如:我希望 00:19:58.582052 变为 00:19:58 或 00:19:58.58

【问题讨论】:

  • 您应该考虑将数据更改为 timedelta 或字符串中的时间戳(如果您有日期)。没有充分的理由将其保留为字符串。然后你可以使用优秀的dt 访问器和floor 方法来截断。看我的回答。

标签: python pandas timedelta


【解决方案1】:

我认为您需要使用 pd.to_timedelta 将字符串转换为 timedelta,然后利用基于字符串截断的 floor 方法利用出色的 dt 访问器。这是您数据的前两行。

df['how_long_it_took_to_order'] = pd.to_timedelta(df['how_long_it_took_to_order'])
df['how_long_it_took_to_order'].dt.floor('s')

0   00:19:58
1   00:25:09

可以四舍五入到百分之一秒。

df['how_long_it_took_to_order'].dt.floor('10ms')

0   00:19:58.580000
1   00:25:09.100000

在这里,我创建了一些时间增量系列,然后使用 dt 访问器和 floor 方法截断到最接近的微秒。

d = pd.timedelta_range(0, periods=6, freq='644257us')
s = pd.Series(d)
s

0          00:00:00
1   00:00:00.644257
2   00:00:01.288514
3   00:00:01.932771
4   00:00:02.577028
5   00:00:03.221285
dtype: timedelta64[ns]

现在截断

s.dt.floor('s')

0   00:00:00
1   00:00:00
2   00:00:01
3   00:00:01
4   00:00:02
5   00:00:03
dtype: timedelta64[ns]

如果您想截断到最接近的百分之一秒,请执行以下操作:

s.dt.floor('10ms')

0          00:00:00
1   00:00:00.640000
2   00:00:01.280000
3   00:00:01.930000
4   00:00:02.570000
5   00:00:03.220000
dtype: timedelta64[ns]

【讨论】:

  • 如果他有字符串就好了。只需将其转换为 timedelta。字符串长度是可变的,但时间增量是准确的
  • 这似乎是一个更理智的答案,而不是修改字符串。
  • 我认为这个解决方案不能正常工作,因为 OP 有两个字符串只代表时间和日期+时间 - 像这样:pd.to_timedelta(['00:19:58.582052', '2014-10-26 13:51:59.898924']) - 这不起作用...
  • @MaxU 有条件地在对您的答案的评论中提到。目前还不清楚海报实际上有什么,但转换为一些时间表示似乎仍然是一种明智的方式。
  • @pvg,你能提出一个解决 OPs 问题而不是“修改字符串”的解决方案吗? ;-)
【解决方案2】:

您的 how_long_it_took_to_order 列似乎是字符串 (object) dtype。

所以试试这个:

analyze_me['how_long_it_took_to_order'] = \
    analyze_me['how_long_it_took_to_order'].str.split('.').str[0]

或:

analyze_me['how_long_it_took_to_order'] = \
    analyze_me['how_long_it_took_to_order'].str.replace('(\.\d{2})\d+', r'\1')

对于“厘秒”,例如:00:19:58.58

【讨论】:

  • 看起来它会完全删除小数部分。
  • @pvg,是的,我就是这么理解的:I want 00:19:58.582052 to become 00:19:58 or 00:19:58.58
  • 有点含糊,但标题是“微秒”。字符串的第二个版本是没​​有微秒的(最多 100 个)。
  • 哇,太棒了!那效果很好。它变成了00:19:58。如果我想在 00:19:58.58 保留 100ths,我需要在代码中更改什么? \ 在这里完成了什么,或者仅仅是来自控制台本身?再次感谢大家-真的很感谢@MaxU 和@pvg
  • \ 只是行的延续,告诉 python 将两行都视为单独的一行。第 100 位代码仍然有点不确定,因为在精度不完全是 6 位十进制数字的情况下它会失败。
【解决方案3】:

我需要这个来编写一个不使用 Pandas 的简单脚本,并想出了一个可以在任何地方都可以使用的简单 hack。

age = age - timedelta(microseconds=age.microseconds)

age 是我的 timedelta 对象。

您不能直接修改 timedelta 对象的 microseconds 成员,因为它是不可变的,但当然,您可以将其替换为另一个不可变对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 2017-09-15
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多