Pandas 滚动时间 window 多列自定义函数
Pandas rolling time window custom functions with multiple columns
我在 pandas DataFrame 中有时间序列数据,如下所示:
ts serial_number device_tp tp
2017-09-19T15:00:00.000Z 4ktpjlv 21.7760333333333 17
2017-09-19T14:00:00.000Z 4ktpjlv 19.8849833333333 16
2017-09-19T13:00:00.000Z 4ktpjlv 18.8565818181818 15
2017-09-19T12:00:00.000Z 4ktpjlv 18.7219666666667 13
2017-09-19T11:00:00.000Z 4ktpjlv 18.8341272727273 13
2017-09-19T10:00:00.000Z 4ktpjlv 18.9697833333333 14
2017-09-19T09:00:00.000Z 4ktpjlv 19.0422416666667 14
我正在尝试计算 tp
和 device_tp
之间的皮尔逊相关系数,并使用滚动时间 window 对每个数据应用动态时间扭曲算法(使用 fastdtw) .对于每个样本,我回顾过去 12 小时并计算相关系数和距离。
我知道 pandas 作为滚动函数,但是,它不是 return 数据框而是一个系列(或数组?)。问题是相关因子和 fastdtw 都需要两个参数才能工作:df.tp
和 df.device_tp
.
我找到了另一种方法,使用循环来达到我想要的效果:
for key, meas in df.iterrows():
now = meas.ts
start_date = now - pd.Timedelta(hours=12)
new_df = df[(df['ts'] >= start_date) & (df['ts'] < now)]
if(new_df.shape[0] > 1):
tp = df.tp.values
device_tp = df.device_tp.values
distance, _ = fastdtw(df['tp'], df['device_tp'])
corr = stats.pearsonr(tp, device_tp)[0]
# ... Predict flag here
if(flag == 0):
output = output.append(meas)
但是当然这真的不合时宜!我还想知道这样做的更好方法是什么?我读了一些关于重新定义滚动函数而不是使用 pandas 内置函数的内容,但真的看不出如何做到这一点。
感谢您的帮助!
好的,所以获得窗口相关性的有效方法是 df["device_tp"].rolling(12, min_periods=2).corr(other=df["tp"])
。
我也想不出获得 DTW 距离的直接方法。
给我大约 8 倍加速的一种解决方案是翻转 pd.Series
个索引,并将生成的索引与 Rolling.apply
:
一起使用
from fastdtw import fastdtw
def rolling_dtw(df, win=12, center=False, min_periods=2,
col0="ts", col1="A", col2="B"):
indices = df[col0]
a = df[col1].values
b = df[col2].values
def rolldist(inds): # calculate DTW for current indices
inds = inds.astype(int) # manual type-cast is needed here
return fastdtw(a[inds], b[inds])[0]
return indices.rolling(win, center=center,
min_periods=min_periods).apply(rolldist)
但是这个解决方案也不太好。假定数据点之间的距离恒定为 1h(以便使用索引)。如果不是这种情况,则需要对其进行调整。
我在 pandas DataFrame 中有时间序列数据,如下所示:
ts serial_number device_tp tp
2017-09-19T15:00:00.000Z 4ktpjlv 21.7760333333333 17
2017-09-19T14:00:00.000Z 4ktpjlv 19.8849833333333 16
2017-09-19T13:00:00.000Z 4ktpjlv 18.8565818181818 15
2017-09-19T12:00:00.000Z 4ktpjlv 18.7219666666667 13
2017-09-19T11:00:00.000Z 4ktpjlv 18.8341272727273 13
2017-09-19T10:00:00.000Z 4ktpjlv 18.9697833333333 14
2017-09-19T09:00:00.000Z 4ktpjlv 19.0422416666667 14
我正在尝试计算 tp
和 device_tp
之间的皮尔逊相关系数,并使用滚动时间 window 对每个数据应用动态时间扭曲算法(使用 fastdtw) .对于每个样本,我回顾过去 12 小时并计算相关系数和距离。
我知道 pandas 作为滚动函数,但是,它不是 return 数据框而是一个系列(或数组?)。问题是相关因子和 fastdtw 都需要两个参数才能工作:df.tp
和 df.device_tp
.
我找到了另一种方法,使用循环来达到我想要的效果:
for key, meas in df.iterrows():
now = meas.ts
start_date = now - pd.Timedelta(hours=12)
new_df = df[(df['ts'] >= start_date) & (df['ts'] < now)]
if(new_df.shape[0] > 1):
tp = df.tp.values
device_tp = df.device_tp.values
distance, _ = fastdtw(df['tp'], df['device_tp'])
corr = stats.pearsonr(tp, device_tp)[0]
# ... Predict flag here
if(flag == 0):
output = output.append(meas)
但是当然这真的不合时宜!我还想知道这样做的更好方法是什么?我读了一些关于重新定义滚动函数而不是使用 pandas 内置函数的内容,但真的看不出如何做到这一点。
感谢您的帮助!
好的,所以获得窗口相关性的有效方法是 df["device_tp"].rolling(12, min_periods=2).corr(other=df["tp"])
。
我也想不出获得 DTW 距离的直接方法。
给我大约 8 倍加速的一种解决方案是翻转 pd.Series
个索引,并将生成的索引与 Rolling.apply
:
from fastdtw import fastdtw
def rolling_dtw(df, win=12, center=False, min_periods=2,
col0="ts", col1="A", col2="B"):
indices = df[col0]
a = df[col1].values
b = df[col2].values
def rolldist(inds): # calculate DTW for current indices
inds = inds.astype(int) # manual type-cast is needed here
return fastdtw(a[inds], b[inds])[0]
return indices.rolling(win, center=center,
min_periods=min_periods).apply(rolldist)
但是这个解决方案也不太好。假定数据点之间的距离恒定为 1h(以便使用索引)。如果不是这种情况,则需要对其进行调整。