J'ai un grand ensemble de données avec plus de 500 000 horodatages qui ressemblent à ceci:
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
Comment arrondir ces horodatages à la seconde près?
Mon code ressemble à ceci:
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))]
Alors maintenant, j'ai combiné les dates et les heures dans une liste d'objets datetime.datetime
Qui ressemble à ceci:
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)
Où dois-je aller d'ici? La fonction df.timestamp.dt.round('1s')
ne semble pas fonctionner? De plus, lorsque j'utilisais .split()
J'avais des problèmes lorsque les secondes et les minutes dépassaient 59
Merci beaucoup
En utilisant for loop
Et str.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
>>>
Vous pouvez transformer cela en fonction:
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
Test de la fonction:
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']
>>>
Comme vous semblez utiliser Python 2.7, pour supprimer les zéros de fin, vous devrez peut-être modifier:
str(round(float(item.split()[1].split(':')[-1])))
à
str(round(float(item.split()[1].split(':')[-1]))).rstrip('0').rstrip('.')
Je viens d'essayer la fonction avec Python 2.7 à repl.it et elle a fonctionné comme prévu.
Sans package supplémentaire, un objet datetime peut être arrondi à la seconde près avec la fonction simple suivante:
import datetime
def roundSeconds(dateTimeObject):
newDateTime = dateTimeObject
if newDateTime.microsecond >= 500000:
newDateTime = newDateTime + datetime.timedelta(seconds=1)
return newDateTime.replace(microsecond=0)
Si vous utilisez des pandas, vous pouvez simplement round
les données à la seconde près en utilisant 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]
Si timestamp
n'est pas une colonne datetime
, convertissez-la d'abord, en utilisant pd.to_datetime
-
df.timestamp = pd.to_datetime(df.timestamp)
Ensuite, dt.round
devrait marcher.
La question ne dit pas comment vous voulez arrondir. L'arrondi serait souvent approprié pour une fonction de temps. Ce ne sont pas des statistiques.
rounded_down_datetime = raw_datetime.replace(microsecond=0)
Si vous stockez un ensemble de données dans un fichier, vous pouvez faire ceci:
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
Si vous stockez un ensemble de données dans une liste:
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)
Version alternative de la solution de @electrovir:
import datetime
def roundSeconds(dateTimeObject):
newDateTime = dateTimeObject + datetime.timedelta(seconds=.5)
return newDateTime.replace(microsecond=0)
Si quelqu'un veut arrondir un seul élément datetime à la seconde près, celui-ci fonctionne très bien:
pandas.to_datetime(your_datetime_item).round('1s')
Une solution élégante qui ne nécessite que le module datetime standard.
import datetime
currentimemili = datetime.datetime.now()
currenttimesecs = currentimemili - \
datetime.timedelta(microseconds=currentimemili.microsecond)
print(currenttimesecs)