Python 和 Pandas:如何在不同分辨率下舍入 Up/Down unix 时间戳 (utc):1min-5min-15min-30min-1H-1D?

Python and Pandas: How to round Up/Down unix timestamp (utc) on different resolutions: 1min-5min-15min-30min-1H-1D?

给定以下时间分辨率示例,舍入 UNIX 时间以获得如下所示结果的最快方法是什么?在简单的 python 和 pandas 数据帧中?

import time
unix_current = int(time.time())
unix_from_down_example = int("1453823631")
unix_from_up_example = int("1453820476")

轮 Down/Up 到 1 分钟

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 15:53:00 | 1453823580 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 26.01.2016 15:02:00 | 1453820520 |
+---------------+---------------------+------------+

轮 Down/Up 到 5 分钟

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 15:50:00 | 1453823400 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 26.01.2016 15:05:00 | 1453820700 |
+---------------+---------------------+------------+

轮 Down/Up 到 15 分钟

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 15:45:00 | 1453823100 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 26.01.2016 15:15:00 | 1453821300 |
+---------------+---------------------+------------+

轮 Down/Up 到 30 分钟

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 15:30:00 | 1453822200 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 26.01.2016 15:30:00 | 1453822200 |
+---------------+---------------------+------------+

Down/Up 到 1 小时

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 15:00:00 | 1453820400 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 26.01.2016 16:00:00 | 1453824000 |
+---------------+---------------------+------------+

将 Down/Up 舍入为 1 天

+---------------+---------------------+------------+
|               |                     | Unix (UTC) |
| from          | 26.01.2016 15:53:51 | 1453823631 |
| to round down | 26.01.2016 00:00:00 | 1453766400 |
|               |                     |            |
| from          | 26.01.2016 15:01:16 | 1453820476 |
| to round up   | 27.01.2016 00:00:00 | 1453852800 |
+---------------+---------------------+------------+

我使用这个 website 作为给定示例的转换参考。

向下舍入的通用公式:

n // <Number of seconds> * <Number of seconds>

向上舍入的通用公式:

n // <Number of seconds> * <Number of seconds> + <Number of seconds>

函数:

def round_unix_date(dt_series, seconds=60, up=False):
    return dt_series // seconds * seconds + seconds * up

用法:

In [204]: df
Out[204]:
        Date1       Date2
0  1453823631  1453820476
1  1453823631  1453820476
2  1453823631  1453820476

In [205]: round_unix_date(df.Date1, 5*60)
Out[205]:
0    1453823400
1    1453823400
2    1453823400
Name: Date1, dtype: int64

In [206]: round_unix_date(df.Date2, 5*60, up=True)
Out[206]:
0    1453820700
1    1453820700
2    1453820700
Name: Date2, dtype: int64

演示(向下舍入):

In [165]: n // (1 * 60) * (1 * 60)
Out[165]: 1453823580

In [166]: n // (5 * 60) * (5 * 60)
Out[166]: 1453823400

In [167]: n = 1453823631

In [168]: n // (1 * 60) * (1 * 60)
Out[168]: 1453823580

In [169]: n // (5 * 60) * (5 * 60)
Out[169]: 1453823400

In [170]: n // (15 * 60) * (15 * 60)
Out[170]: 1453823100

In [171]: n // (30 * 60) * (30 * 60)
Out[171]: 1453822200

In [172]: n // (60 * 60) * (60 * 60)
Out[172]: 1453820400

In [173]: n // (24 * 60 * 60) * (24 * 60 * 60)
Out[173]: 1453766400

演示(四舍五入):

In [188]: n = 1453820476

In [189]: n // (1 * 60) * (1 * 60) + 60
Out[189]: 1453820520

In [191]: n // (5 * 60) * (5 * 60) + 5*60
Out[191]: 1453820700

In [192]: n // (15 * 60) * (15 * 60) + 15*60
Out[192]: 1453821300

...

更新:

In [226]: round_unix_date(df.Date1, 24*60*60)
Out[226]:
0    1453766400
1    1453766400
2    1453766400
Name: Date1, dtype: int64

In [227]: round_unix_date(df.Date2, 24*60*60, up=True)
Out[227]:
0    1453852800
1    1453852800
2    1453852800
Name: Date2, dtype: int64

我不知道 Pandas 中有任何功能可以帮助您完成此任务。一个好的解决方案是只编写一个 Python 函数,然后您可以使用 pandas.[=15 中的 apply 函数将其应用于数据框的列=]

将您的时间戳列转换为日期时间对象。这应该可以帮助您轻松获得不同单位的时间戳。

这里有一些逻辑可以帮助你:

from datetime import datetime, timedelta

t = datetime(2011,10,15,12,30,15)

四舍五入1分钟

只需截断秒字段以进行向下舍入。如果向下舍入,则增加一分钟并截断一秒钟。

# round down
t_down = t.replace(second=0)

# round up
t += timedelta(minutes=1)
t_up = t.replace(second=0)

四舍五入

您将不得不在这里玩一些 mod 算术。下面的示例是 5 分钟,但您可以通过将 5 替换为所需的分钟数来将 mod 延长 15 和 30 分钟。

# round down
diff = t.minute % 5
t_sub = timedelta(minutes=diff)
t_down = t - t_sub

# round up
diff = t.minute % 5
t_sub = timedelta(minutes=5-diff)
t_up = t + t_sub

1 小时一圈

使用与 1 分钟相同的方法,使用小时而不是分钟。

# round down
t_down = t.replace(minute=0, second=0)

# round up
t += timedelta(hours=1)
t_up = t.replace(minute=0, second=0)

四舍五入 1 天

再次延长 1 分钟和 1 小时的示例。

# round down
t_down = t.replace(hour=0 ,minute=0, second=0)

# round up
t += timedelta(days=1)
t_up = t.replace(hour=0, minute=0, second=0)

一个好主意是为您要处理的每个案例创建一个函数。然后有另一个函数根据用户想要执行的当前任务调用这些函数之一。