efs*_*see 5 python timestamp time-series pandas
我有一个大数据框,其中包含大约 7,000,000 行时间序列数据,如下所示
timestamp | values
2019-08-01 14:53:01 | 20.0
2019-08-01 14:53:55 | 29.0
2019-08-01 14:53:58 | 22.4
...
2019-08-02 14:53:25 | 27.9
Run Code Online (Sandbox Code Playgroud)
我想为每行创建一个滞后版本 1 天的列,因为我的时间戳不完全匹配,所以我无法使用正常方法shift()。结果将是这样的:
timestamp | values | lag
2019-08-01 14:53:01 | 20.0 | Nan
2019-08-01 14:53:55 | 29.0 | Nan
2019-08-01 14:53:58 | 22.4 | Nan
...
2019-08-02 14:53:25 | 27.9 | 20.0
Run Code Online (Sandbox Code Playgroud)
我发现了一些与获取与给定时间最接近的时间戳相关的帖子:Find close row of DataFrame to给定时间 in Pandas并尝试了这些方法,它可以完成工作,但运行时间太长,这就是我所拥有的:
def get_nearest(data, timestamp):
index = data.index.get_loc(timestamp,"nearest")
return data.iloc[index, 0]
df['lag'] = [get_nearest(df, dt) for dt in df.index]
Run Code Online (Sandbox Code Playgroud)
有什么有效的方法可以解决问题吗?
假设您的日期已排序,快速完成此操作的一种方法是使用pd.DateTimeIndex.searchsorted及时查找所有匹配的日期O[N log N]。
创建一些测试数据,它可能看起来像这样:
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(
{'values': np.random.rand(10)},
index=sorted(np.random.choice(pd.date_range('2019-08-01', freq='T', periods=10000), 10, replace=False))
)
def add_lag(df):
ind = df.index.searchsorted(df.index - pd.DateOffset(1))
out_of_range = (ind <= 0) | (ind >= df.shape[0])
ind[out_of_range] = 0
lag = df['values'].values[ind]
lag[out_of_range] = np.nan
df['lag'] = lag
return df
add_lag(df)
Run Code Online (Sandbox Code Playgroud)
values lag
2019-08-01 06:17:00 0.548814 NaN
2019-08-01 10:51:00 0.715189 NaN
2019-08-01 13:56:00 0.602763 NaN
2019-08-02 09:50:00 0.544883 0.715189
2019-08-03 14:06:00 0.423655 0.423655
2019-08-04 03:00:00 0.645894 0.423655
2019-08-05 07:40:00 0.437587 0.437587
2019-08-07 00:41:00 0.891773 0.891773
2019-08-07 07:05:00 0.963663 0.891773
2019-08-07 15:55:00 0.383442 0.891773
Run Code Online (Sandbox Code Playgroud)
通过这种方法,可以在数十毫秒内计算出具有 100 万行的数据帧:
df = pd.DataFrame(
{'values': np.random.rand(1000000)},
index=sorted(np.random.choice(pd.date_range('2019-08-01', freq='T', periods=10000000), 1000000, replace=False))
)
%timeit add_lag(df)
# 10 loops, best of 3: 71.5 ms per loop
Run Code Online (Sandbox Code Playgroud)
但请注意,这并不是找到最接近一天滞后的值,而是找到滞后一天之后的最接近值。如果您想要任一方向上最接近的值,则需要修改此方法。
| 归档时间: |
|
| 查看次数: |
6053 次 |
| 最近记录: |