在时间戳边界之间填充 Pandas 列

Filling Pandas column between timestamp boundaries

让我们考虑一个包含一列时间戳和第二列测量值的数据帧。

    import pandas as pd

    data = {'Time':  [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
            'Value': [13,54,68,94,31,68,46,46,31,53,54,85,75,42,69]}

    df = pd.DataFrame (data, columns = ['Time','Value'])

我们想过滤数据帧以仅保留特定时间的值。

    start = [2, 9, 14]
    end = [5, 12, 15]

在这种情况下,我们要保留 3 个时间范围;从 2s 到 5s,从 9s 到 12s,从 14s 到 15s。 我创建了一个列来标记我们要保留的时间范围的边界。

    df.loc[df["Time"].isin(start), "Observation"] = 'Start'
    df.loc[df["Time"].isin(end), "Observation"] = 'End'

为了过滤行,我想填充开始和结束之间的单元格,并删除空行。这就是我被困的地方。

我尝试使用:

    df = df.fillna(method='ffill')

这种方法的问题是我只需要将此填充应用到开始(填充观察时间范围内)但我不想在“结束”之后填充。

我的第一个想法是创建另一组时间戳,将会话结束时的时间戳加 1:

    import pandas as pd

    data = {'Time':  [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
            'Value': [13,54,68,94,31,68,46,46,31,53,54,85,75,42,69]}

    df = pd.DataFrame (data, columns = ['Time','Value'])

    start = [2, 9, 14]
    end = [5, 12, 15]
    out = [x+1 for x in end]

    df.loc[df["Time"].isin(start), "Observation"] = 'Start'
    df.loc[df["Time"].isin(end), "Observation"] = 'End'
    df.loc[df["Time"].isin(out), "Observation"] = 'Out'

    df = df.fillna(method='ffill')

这种方法的问题是,对于我要解决的问题,时间戳不是固定时间间隔的秒数。它是随机间隔的毫秒数,因此使用此 +1 来创建“Out”标记不是一种可靠的方法,并且感觉我将应该简单的事情复杂化了;只保留开始时间戳和结束时间戳之间的观察结果(包括两个时间戳)。

使用过滤器 (filter/select rows of pandas dataframe by timestamp column) 可能是一种选择。但是,根据我正在查看的会话,可能会有随机数量的感兴趣的时间范围。我想尝试使用 for 循环扫描开始时间戳列表和结束时间戳列表来动态创建这样的过滤器,但我没能成功。

如果有人知道一个函数可以完全满足我的需要,或者有任何提示,那就太好了。

谢谢。

如何创建压缩 startend 列表的函数并检查元素是否在给定值对内:

def catch_df(start, end, element):
    start_end = zip(start, end)
    for i, z in enumerate(start_end):
        if element >= z[0] and element <= z[1]:
            return "df{}".format(i)

并将该函数应用于存储在数据框中的值 df:

df['Result'] = df['Time'].apply(lambda x: catch_df(start, end, x))

因此您会收到以下数据框,可以轻松过滤 None 值等:

    Time Value  Observation Result
0   1    13     NaN         None
1   2    54     Start       df0
2   3    68     NaN         df0
3   4    94     NaN         df0
4   5    31     End         df0
5   6    68     NaN         None
6   7    46     NaN         None
7   8    46     NaN         None
8   9    31     Start       df1
9   10   53     NaN         df1
10  11   54     NaN         df1
11  12   85     End         df1
12  13   75     NaN         None
13  14   42     Start       df2
14  15   69     End         df2