python - pandas 中的半小时四舍五入

标签 python pandas dataframe datetime hour

pandas 中的

round() 函数将时间 07:30 向下舍入到 07:00 但我想对超过 30 分钟(含)的任何时间进行舍入。

例如。

07:15 to 07:00
05:25 to 05:00
22:30 to 23:00
18:45 to 19:00

如何使用 pandas 对数据框的列实现此目的?

最佳答案

时间戳

您需要使用dt.round 。然而,这有点像前一小时/下一小时的行为取决于该小时本身。您可以通过增加或减少少量时间(此处为 1ns)来强制执行:

s = pd.to_datetime(pd.Series(['1/2/2021 3:45', '25/4/2021 12:30', 
                              '25/4/2021 13:30', '12/4/2022 23:45']))

# xx:30 -> rounding depending on the hour parity (default)
s.dt.round(freq='1h')

0   2021-01-02 04:00:00
1   2021-04-25 12:00:00    <- -30min
2   2021-04-25 14:00:00    <- +30min
3   2022-12-05 00:00:00
dtype: datetime64[ns]


# 00:30 -> 00:00 (force down)
s.sub(pd.Timedelta('1ns')).dt.round(freq='1h')

0   2021-01-02 04:00:00
1   2021-04-25 12:00:00
2   2021-04-25 13:00:00
3   2022-12-05 00:00:00
dtype: datetime64[ns]


# 00:30 -> 01:00 (force up)
s.add(pd.Timedelta('1ns')).dt.round(freq='1h')

0   2021-01-02 04:00:00
1   2021-04-25 12:00:00
2   2021-04-25 13:00:00
3   2022-12-05 00:00:00
dtype: datetime64[ns]

float

IIUC,您可以使用divmod (或 numpy.modf )获取整数和小数部分,然后执行简单的 bool 运算:

s = pd.Series([7.15, 5.25, 22.30, 18.45])

s2, r = s.divmod(1)  # or np.modf(s)

s2[r.ge(0.3)] += 1

s2 = s2.astype(int)

替代方案:使用 mod和 bool 值到 int 的等价:

s2 = s.astype(int)+s.mod(1).ge(0.3)

输出:

0     7
1     5
2    23
3    19
dtype: int64

关于精度的说明。由于浮点运算,比较 float 并不总是那么容易。例如,使用 gt 在 22.30 上会失败。为了确保精度首先四舍五入到 2 位数字。

s.mod(1).round(2).ge(0.3)

或使用整数:

s.mod(1).mul(100).astype(int).ge(30)

关于python - pandas 中的半小时四舍五入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71858940/

相关文章:

python setup.py 配置在自定义目录中安装文件

python - 在django中读取Ajax post数据

python - 求和 pandas 数据框中字符串的出现次数

python - Pandas 找到最后一个非 NAN 值

python - 如何通过字符串值和行中匹配的整数来过滤 Pandas 数据框?

python - 是否可以在 shell 命令中的反引号之间执行 Python 程序?

Python:如何通过排除第三个目录来使用 tarfile 模块获取 tar

python - 估计每组中唯一出现的次数

python - Pandas 数据框。按值分组并计数

python - 在 Pandas DataFrame 中除以两个数字时出现奇怪的错误