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)
一个好主意是为您要处理的每个案例创建一个函数。然后有另一个函数根据用户想要执行的当前任务调用这些函数之一。
给定以下时间分辨率示例,舍入 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)
一个好主意是为您要处理的每个案例创建一个函数。然后有另一个函数根据用户想要执行的当前任务调用这些函数之一。