我有一个格式为%H:%M:%S的时间戳。通过下面的函数,我得到了经过的时间。
# time diff func
def time_diff(t1, t2):
return datetime.strptime(t1, '%H:%M:%S') - datetime.strptime(t2, '%H:%M:%S')
# elapsed time since start
data['time'] = [time_diff(data['time'][i], data['time'][0]) for i in range(len(data['time']))]
我还想计算连续数据之间的时间间隔。因此,第一条和第二条之间的时间间隔,第二条和第三条之间的时间间隔,以此类推。下面的列表理解可以完成这个工作。
# get timedelta
timedeltas = [data['time'][i] - data['time'][i-1] for i in range(1 ,len(data['time']))]
结果从第一个和第二个条目之间的timedelta开始。但我希望列表理解从比较第一个条目开始,所以我得到的第一个结果是00:00:00,然后开始比较元素和连续的元素(第一个和第二个,第二个和第三个,...)。有人知道如何解决这个问题吗?
一个非常Pythonic的方法是完全避免使用subsripting(分片),只用下面的方法。
[0] + [time_diff(t1, t0) for (t1, t0) in zip(data[1:], data[:-1])]
zip
两个子列表--一个从第二个元素元素开始,一直到最后,另一个从第一个元素开始,一直到下一个或最后一个元素。你可以通过替换掉以下代码来提高性能和内存消耗 data[:-1]
......这将防止创建一个临时列表 data[:-1]
,并且不会改变功能,因为 zip
只有在两个列表都没有用完的时候才会操作。这段代码有点脏,不过(IMHO),因为你把不等长的 list 发送给了 zip
.
你也可以跳过创建 data[1:]
临时列表,通过做。
data_i = iter(data)
next(data_i)
diff = [0] + [time_diff(t1, t0) for (t1, t0) in zip(data_i, data)]
现在你只用了三行代码,但并没有创建任何临时列表,也没有随机访问列表(只使用顺序访问)。
你可以进一步简化使用 itertools.islice
:
from itertools import islice
diff = [0] + [time_diff(t1, t0) for (t1, t0) in zip(islice(data, 1, None), data)]
你试过了吗?
# get timedelta
timedeltas = [data['time'][i] - data['time'][i-1] if i > 0 else data['time'][i]-data['time'][i] for i in range(len(data['time']))]
虽然它很丑陋。我认为代码
timedeltas = [data['time'][0]-data['time'][0]] + [data['time'][i] - data['time'][i-1] for i in range(1 ,len(data['time']))]
更容易读懂
你可以用 pandas
:
import pandas as pd
# I suppose your data is a dictionary
data = {'time': ['12:13:11', '12:14:15', '13:20:31']}
df = pd.DataFrame(data=data)
df.time = pd.to_datetime(df.time)
df['timedeltas'] = df.time.diff() # Produces NaT to first index
df.timedeltas.fillna(pd.Timedelta(seconds=0), inplace=True) # Replaces NaT values with 0-second Timedelta
print(df)
>>>
time timedeltas
0 2020-05-13 12:13:11 00:00:00
1 2020-05-13 12:14:15 00:01:04
2 2020-05-13 13:20:31 01:06:16
希望能帮到你