创建时间序列数据框的最快方法

Fastest way to create time series dataframe

我想获取包含时间间隔和时间 重复 的数据,并基本上使用任何给定时间的第一次出现和向前填充来创建时间序列。考虑以下示例。

假设这是我们感兴趣的时间范围:

Time
1:00
1:01
1:02
1:03
1:04
1:05

这是数据,数据框 X,我们想放入我们的时间序列中:

Occurance Value
1:00 "R"
1:03 "G"
1:03 "L"
1:03 "P"
1:03 "T"
1:05 "S"

这是最终数据框:

Occurance Value
1:00 "R"
1:01 "R"
1:02 "R"
1:03 "G"
1:04 "G"
1:05 "S"

如您所见,在最终数据帧中,1:00 的值为“R”,因为这是数据帧 X 中 1:00 第一次出现时的值。1:01并且 1:02 也具有值“R”,因为在数据帧 X 中没有这些时间实例的数据,因此将使用最后一个有效值(即 1:00 的值)。 1:03 具有值“G”,因为与 1:00 的情况类似,“G”是我们在数据帧 X 中拥有的 1:03 的第一个值。由于没有值1:04 在数据帧 X 中,1:04 获取我们生成的数据帧中的最后一个有效值“G”。最后,1:05 在我们生成的数据帧中将具有值“S”,因为这是数据帧 X 中第一次出现 1:05 的值。

完成此操作的最快方法是什么?

merge_asof

请参阅下面的解决方案以查看最终解决方案。

首先,我们需要将这些列更改为 pd.Timedelta:

df1['Time'] = pd.to_timedelta(df1['Time'] + ':00')
df2['Occurance'] = pd.to_timedelta(df2['Occurance'] + ':00')

那我们可以merge_asof

pd.merge_asof(df1, df2, left_on='Time', right_on='Occurance')

             Time       Occurance Value
0 0 days 01:00:00 0 days 01:00:00     R
1 0 days 01:01:00 0 days 01:00:00     R
2 0 days 01:02:00 0 days 01:00:00     R
3 0 days 01:03:00 0 days 01:03:00     T
4 0 days 01:04:00 0 days 01:03:00     T
5 0 days 01:05:00 0 days 01:05:00     S

这有几个问题:

  1. 列数多于 OP 指定的列数。
  2. 我有 Ts 而不是 Gs

好的,为了去掉列,我们只是重命名其中一列,而不是使用 left_on/right_on

pd.merge_asof(df1.set_axis(['Occurance'], axis=1), df2)

        Occurance Value
0 0 days 01:00:00     R
1 0 days 01:01:00     R
2 0 days 01:02:00     R
3 0 days 01:03:00     T
4 0 days 01:04:00     T
5 0 days 01:05:00     S

但我们仍然有 T 而不是 G,那是因为看 df2

        Occurance Value
0 0 days 01:00:00     R
1 0 days 01:03:00     G  # same Occurance
2 0 days 01:03:00     L  # same Occurance
3 0 days 01:03:00     P  # same Occurance
4 0 days 01:03:00     T  # same Occurance
5 0 days 01:05:00     S

显然,Pandas 拿了最后一个,而 OP 想要第一个。所以让我们再试一次 drop_duplicates

解决方案

pd.merge_asof(df1.set_axis(['Occurance'], axis=1),
              df2.drop_duplicates('Occurance'))

        Occurance Value
0 0 days 01:00:00     R
1 0 days 01:01:00     R
2 0 days 01:02:00     R
3 0 days 01:03:00     G
4 0 days 01:04:00     G
5 0 days 01:05:00     S