按给定的时间间隔在数据帧列中查找时间戳

2024-09-29 23:24:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含时间戳列的数据帧。我的目标是找到每一行的第一个时间戳,它比该行的时间戳大一个给定的偏移量(比如0.01秒)。我试着使用the answer given here,用一种修改过的方式,比如:

def getTime(col, base, offset=0.01):
    later = filter(lambda d: d > base+dt.timedelta(seconds=offset), col)
    return min(later)

testTbt['testTime']=testTbt['exchTstamp'].apply(lambda time: getTime(testTbt[testTbt['exchTstamp']>time]['exchTstamp'].iloc[0:100].tolist(), time, 0.01))

但是得到了错误:ValueError: min() arg is an empty sequence。你知道吗

时间戳是微秒级的,包含重复值,并且按递增顺序排列。你知道吗

以下是数据框的初始行:

    exchTstamp                  seqNum prev10mSecAvg prev1SecAvg    imbRegime
0   2019-08-14  09:15:00.022991 199    0.000000      0.000000       0
1   2019-08-14  09:15:00.022995 200   -0.166667     -0.166667       3
2   2019-08-14  09:15:00.022999 201   -0.277778     -0.277778       2
3   2019-08-14  09:15:00.023003 202   -0.333333     -0.333333       2
4   2019-08-14  09:15:00.023007 203   -0.386667     -0.386667       2

csv的数据可以下载here。你知道吗

预期输出是数据帧中添加的一列,包含来自后续时间戳的第一个时间戳,该时间戳至少比当前行的时间戳大0.01秒。例如:-对于给定的数据集,第一行的新列(有时间09:15:00.022995)应该有值09:15:00.033136。以后的每一行都一样。你知道吗

一点指导会很有帮助。你知道吗


Tags: 数据lambda目标baseheretime时间col
3条回答

我认为最快最简单的方法是使用^{}。如果没有大于df.exchTstamp+delta的元素,那么searchsorted将返回数组的长度,即一个索引超出了数据帧索引的界限。因此,我们首先需要为本例插入一个nan/NaTsentinel行,然后删除它:

import numpy as np, pandas as pd, datetime as dt

df = pd.read_csv('stack.csv', index_col=0, parse_dates=[1])
delta = dt.timedelta(seconds=0.01)

res = np.searchsorted(df.exchTstamp, df.exchTstamp+delta)

# add sentinel
df.append(pd.Series(), ignore_index=True)

df["testTime"] = df.loc[res,'exchTstamp'].values

# remove sentinel
df = df.drop(df.index[-1])

df.to_csv('stack-out.csv')

“Filter”在数据帧的末尾生成空列表。而且,由于数据是按时间顺序排列的,所以获得比基本时间戳更大的时间戳是一种奢侈。你知道吗

import numpy as np, pandas as pd, datetime as dt

df=pd.read_csv("stack.csv",parse_dates=[1],index_col=0)

l=[]       

for i in df.index: 
    l.append(None) 
    start=df.at[i,"exchTstamp"] 
    for k in range(i+1,len(df.index)): 
        if start<=df.at[k,"exchTstamp"]-dt.timedelta(seconds=0.01): 
            l[-1]=df.at[k,"exchTstamp"] 
            break 

df["testTime"]= l 

好吧,也许不是处理这样的问题的最优雅的方法,但这样可以完成任务:

import numpy as np
import pandas as pd

df = pd.read_csv("stack.csv", index_col=0)
df["exchTstamp"] = df["exchTstamp"].apply(pd.to_datetime)

def getTime(base_idx, offset=0.01):
    time_delta, i = 0, 0
    while time_delta < offset:
        time_delta = (df["exchTstamp"][base_idx + i] - df["exchTstamp"][base_idx]).total_seconds()
        i += 1
        if base_idx + i == len(df.index):
            return(np.nan)
    return(df["exchTstamp"][base_idx + i])

df["testTime"] = [getTime(j) for j in range(len(df.index))]

这就给了你:

df.head(10)
    exchTstamp                 seqNum rev10mSecAvg prev1SecAvg imbRegime    testTime
0   2019-08-14 09:15:00.022991  199    0.000000    0.000000 0   2019-08-14 09:15:00.033136
1   2019-08-14 09:15:00.022995  200   -0.166667   -0.166667 3   2019-08-14 09:15:00.033136
2   2019-08-14 09:15:00.022999  201   -0.277778   -0.277778 2   2019-08-14 09:15:00.033136
3   2019-08-14 09:15:00.023003  202   -0.333333   -0.333333 2   2019-08-14 09:15:00.033136
4   2019-08-14 09:15:00.023007  203   -0.386667   -0.386667 2   2019-08-14 09:15:00.033136
5   2019-08-14 09:15:00.023011  204   -0.422222   -0.422222 0   2019-08-14 09:15:00.033136
6   2019-08-14 09:15:00.023015  205   -0.447619   -0.447619 0   2019-08-14 09:15:00.033136
7   2019-08-14 09:15:00.023018  206   -0.475000   -0.475000 0   2019-08-14 09:15:00.033136
8   2019-08-14 09:15:00.023023  207   -0.422222   -0.422222 1   2019-08-14 09:15:00.033136
9   2019-08-14 09:15:00.023027  208   -0.380000   -0.380000 3   2019-08-14 09:15:00.033136

相关问题 更多 >

    热门问题