舍入时间到最接近的秒 - Python

时间:2017-12-13 11:47:04

标签: python python-2.7 pandas datetime

我有一个超过500 000日期&的大型数据集。时间戳看起来像这样:

date        time
2017-06-25 00:31:53.993
2017-06-25 00:32:31.224
2017-06-25 00:33:11.223
2017-06-25 00:33:53.876
2017-06-25 00:34:31.219
2017-06-25 00:35:12.634 

如何将这些时间戳舍入到最接近的秒?

我的代码如下所示:

readcsv = pd.read_csv(filename)
log_date = readcsv.date
log_time = readcsv.time

readcsv['date'] = pd.to_datetime(readcsv['date']).dt.date
readcsv['time'] = pd.to_datetime(readcsv['time']).dt.time
timestamp = [datetime.datetime.combine(log_date[i],log_time[i]) for i in range(len(log_date))]

所以现在我将日期和时间合并到一个datetime.datetime对象列表中,如下所示:

datetime.datetime(2017,6,25,00,31,53,993000)
datetime.datetime(2017,6,25,00,32,31,224000)
datetime.datetime(2017,6,25,00,33,11,223000)
datetime.datetime(2017,6,25,00,33,53,876000)
datetime.datetime(2017,6,25,00,34,31,219000)
datetime.datetime(2017,6,25,00,35,12,634000)

我从哪里开始? df.timestamp.dt.round('1s')功能似乎无法正常工作? 使用.split()时,当秒和分钟超过59

时,我遇到了问题

非常感谢

11 个答案:

答案 0 :(得分:5)

如果没有任何额外的包,可以使用以下简单函数将datetime对象四舍五入到最接近的秒:

import datetime

def roundSeconds(dateTimeObject):
    newDateTime = dateTimeObject

    if newDateTime.microsecond >= 500000:
        newDateTime = newDateTime + datetime.timedelta(seconds=1)

    return newDateTime.replace(microsecond=0)

答案 1 :(得分:3)

如果你正在使用pandas,你可以使用round { - 1}}将数据dt.round提取到最接近的第二位 -

df

                timestamp
0 2017-06-25 00:31:53.993
1 2017-06-25 00:32:31.224
2 2017-06-25 00:33:11.223
3 2017-06-25 00:33:53.876
4 2017-06-25 00:34:31.219
5 2017-06-25 00:35:12.634

df.timestamp.dt.round('1s')

0   2017-06-25 00:31:54
1   2017-06-25 00:32:31
2   2017-06-25 00:33:11
3   2017-06-25 00:33:54
4   2017-06-25 00:34:31
5   2017-06-25 00:35:13
Name: timestamp, dtype: datetime64[ns]

如果timestamp不是datetime列,请先使用pd.to_datetime -

进行转换
df.timestamp = pd.to_datetime(df.timestamp)

然后,dt.round应该有用。

答案 2 :(得分:2)

如果有人想将单个日期时间项四舍五入到最接近的秒数,则该方法就可以了:

function DrawRoom(width, height, x, y) {
var svgContainer = jQuery(canvas.getHtmlContainer()).find('svg');
svgContainer.html('<defs><pattern id="background-images" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse"><image xlink:href="https://cdna.artstation.com/p/assets/images/images/008/218/168/large/altheia-frane-wood-texture.jpg?151126541" x="0" y="0" width="50" height="50"></image></pattern></defs>');

var room = new draw2d.shape.composite.Jailhouse({
    width: width, 
    height: height, 
    x: x, 
    y: y,
    bgColor: 'url(#image)'
});
canvas.add(room);
//this below doesn't work
var color = new draw2d.util.Color("url(#background-images)");
room.setBackgroundColor(color);
}

答案 3 :(得分:1)

如果要将数据集存储到文件中,可以这样做:

with open('../dataset.txt') as fp:
    line = fp.readline()
    cnt = 1
    while line:
        line = fp.readline()
        print "\n" + line.strip()
        sec = line[line.rfind(':') + 1:len(line)]
        rounded_num = int(round(float(sec)))
        print line[0:line.rfind(':') + 1] + str(rounded_num)
        print abs(float(sec) - rounded_num)
        cnt += 1

如果要将数据集存储在列表中:

dts = ['2017-06-25 00:31:53.993',
   '2017-06-25 00:32:31.224',
   '2017-06-25 00:33:11.223',
   '2017-06-25 00:33:53.876',
   '2017-06-25 00:34:31.219',
   '2017-06-25 00:35:12.634']

for i in dts:
    line = i
    print "\n" + line.strip()
    sec = line[line.rfind(':') + 1:len(line)]
    rounded_num = int(round(float(sec)))
    print line[0:line.rfind(':') + 1] + str(rounded_num)
    print abs(float(sec) - rounded_num)

答案 4 :(得分:1)

@electrovir解决方案的替代版本:

import datetime

def roundSeconds(dateTimeObject):
    newDateTime = dateTimeObject + datetime.timedelta(seconds=.5)
    return newDateTime.replace(microsecond=0)

答案 5 :(得分:0)

使用for loopstr.split()

dts = ['2017-06-25 00:31:53.993',
       '2017-06-25 00:32:31.224',
       '2017-06-25 00:33:11.223',
       '2017-06-25 00:33:53.876',
       '2017-06-25 00:34:31.219',
       '2017-06-25 00:35:12.634']

for item in dts:
    date = item.split()[0]
    h, m, s = [item.split()[1].split(':')[0],
               item.split()[1].split(':')[1],
               str(round(float(item.split()[1].split(':')[-1])))]

    print(date + ' ' + h + ':' + m + ':' + s)

2017-06-25 00:31:54
2017-06-25 00:32:31
2017-06-25 00:33:11
2017-06-25 00:33:54
2017-06-25 00:34:31
2017-06-25 00:35:13
>>> 

你可以把它变成一个函数:

def round_seconds(dts):
    result = []
    for item in dts:
        date = item.split()[0]
        h, m, s = [item.split()[1].split(':')[0],
                   item.split()[1].split(':')[1],
                   str(round(float(item.split()[1].split(':')[-1])))]
        result.append(date + ' ' + h + ':' + m + ':' + s)

    return result

测试功能:

dts = ['2017-06-25 00:31:53.993',
       '2017-06-25 00:32:31.224',
       '2017-06-25 00:33:11.223',
       '2017-06-25 00:33:53.876',
       '2017-06-25 00:34:31.219',
       '2017-06-25 00:35:12.634']

from pprint import pprint

pprint(round_seconds(dts))

['2017-06-25 00:31:54',
 '2017-06-25 00:32:31',
 '2017-06-25 00:33:11',
 '2017-06-25 00:33:54',
 '2017-06-25 00:34:31',
 '2017-06-25 00:35:13']
>>> 

由于您似乎使用Python 2.7,要删除任何尾随零,您可能需要更改:

str(round(float(item.split()[1].split(':')[-1])))

str(round(float(item.split()[1].split(':')[-1]))).rstrip('0').rstrip('.')

我刚刚在repl.it尝试使用Python 2.7的功能,并按预期运行。

答案 6 :(得分:0)

该问题并没有说明您想要四舍五入的方法。四舍五入通常适合于时间功能。这不是统计信息。

rounded_down_datetime = raw_datetime.replace(microsecond=0) 

答案 7 :(得分:0)

仅需标准datetime模块的优雅解决方案。

import datetime

            currentimemili = datetime.datetime.now()
            currenttimesecs = currentimemili - \
                datetime.timedelta(microseconds=currentimemili.microsecond)
            print(currenttimesecs)

答案 8 :(得分:0)

我需要它,所以我将@srisaila调整为以60秒/分钟的速度工作。样式极其复杂,但是基本功能。

def round_seconds(dts):
    result = []
    for item in dts:
        date = item.split()[0]
        h, m, s = [item.split()[1].split(':')[0],
                   item.split()[1].split(':')[1],
                   str(round(float(item.split()[1].split(':')[-1])))]
        if len(s) == 1:
            s = '0'+s
        if int(s) == 60:
            m_tmp = int(m)
            m_tmp += 1
            m = str(m_tmp)
            if(len(m)) == 1:
                m = '0'+ m
            s = '00'
        if m == 60:
            h_tmp = int(h)
            h_tmp += 1
            h = str(h_tmp)
            if(len(h)) == 1:
                print(h)
                h = '0'+ h
            m = '00'
        result.append(date + ' ' + h + ':' + m + ':' + s)
    return result

答案 9 :(得分:0)

另一种方法:

  • 不涉及字符串操作
  • 使用 Python 的内置 round
  • 不会改变原始的时间增量,而是提供一个新的时间增量
  • 是单班轮:)
import datetime

original = datetime.timedelta(seconds=50, milliseconds=20)
rounded = datetime.timedelta(seconds=round(original.total_seconds()))

答案 10 :(得分:0)

这是一个简单的解决方案,它可以正确地四舍五入并且不使用任何字符串技巧:

from datetime import datetime, timedelta

def round_to_secs(dt: datetime) -> datetime:
    extra_sec = round(dt.microsecond / 10 ** 6)
    return dt.replace(microsecond=0) + timedelta(seconds=extra_sec)

一些例子:

now = datetime.now()
print(now)                 # 2021-07-26 10:43:54.397538
print(round_to_secs(now))  # 2021-07-26 10:43:54 -- rounded down

now = datetime.now()
print(now)                 # 2021-07-26 10:44:59.787438
print(round_to_secs(now))  # 2021-07-26 10:45:00  -- rounded up taking into account secs and minutes