对 float64 与 object 和 int64 列的不同条件的时间序列进行上采样
Upsampling a time-series with different conditions for float64 vs object and int64 columns
我有一个 df
类似于:
print(df)
A B C
DATE_TIME
2016-10-08 13:57:00 in 5.61 0
2016-10-08 14:02:00 in 8.05 0
2016-10-08 14:07:00 out 7.92 0
2016-10-08 14:12:00 in 7.98 1
2016-10-08 14:17:00 out 8.18 0
2016-10-08 14:22:00 out 7.59 0
print (df.dtypes)
A object
B float64
C int64
dtype: object
我想将此 df
重新采样为 1S 频率,以便我可以将它与另一个 df
连接起来。
我无法解决的问题是,对于 object
和 int64
类型的列,我希望为新创建的时间行重复相同的值,这可以通过此函数完成:
df=df.resample('S', fill_method='pad')
而对于 float64
列,我正在寻找这个:
df=df.interpolate()
我考虑过应用 IF 语句,但我也认为我首先必须在插值步骤之前执行重采样步骤。当我仅按 df=df.resample('S')
重新采样时,我可以在之后进行插值,这适用于 float64
列但不适用于 object
和 Int64
列。
有人可以帮我吗?谢谢。
这是一个使用reindex
的方法:
index = pd.date_range(df.index[0], df.index[-1], freq="s")
df2 = df.reindex(index)
for col, s in df2.iteritems():
if s.dtype == float:
s.interpolate(inplace=True)
else:
s.ffill(inplace=True)
更新: 我认为你仍然可以使用矢量化方法(而不是循环遍历你的数据框),即使你有多个 float
列 - 它应该很多更快:
假设您有以下 DF(列:['B','D']
属于 float
dtype):
In [18]: df
Out[18]:
A B C D
DATE_TIME
2016-10-08 13:57:00 in 5.61 0 6.2271
2016-10-08 14:02:00 in 8.05 0 8.9355
2016-10-08 14:07:00 out 7.92 0 8.7912
2016-10-08 14:12:00 in 7.98 1 8.8578
2016-10-08 14:17:00 out 8.18 0 9.0798
2016-10-08 14:22:00 out 7.59 0 8.4249
In [19]: df.dtypes
Out[19]:
A object
B float64
C int64
D float64
dtype: object
您可以执行以下操作(它适用于 pandas 版本:0.18.0+):
rsmpl = df.resample('S')
pd.concat([rsmpl.pad()[df.select_dtypes(exclude=['float']).columns],
rsmpl.interpolate()[df.select_dtypes(include=['float']).columns]],
axis=1)
示例:
In [23]: pd.concat([rsmpl.pad()[df.select_dtypes(exclude=['float']).columns],
....: rsmpl.interpolate()[df.select_dtypes(include=['float']).columns]],
....: axis=1).head()
Out[23]:
A C B D
DATE_TIME
2016-10-08 13:57:00 in 0 5.610000 6.227100
2016-10-08 13:57:01 in 0 5.618133 6.236128
2016-10-08 13:57:02 in 0 5.626267 6.245156
2016-10-08 13:57:03 in 0 5.634400 6.254184
2016-10-08 13:57:04 in 0 5.642533 6.263212
旧答案:
您可以先 resample('S')
和 pad()
,然后将 float64
列 B
重新分配给 df.resample('S').interpolate().B
:
In [96]: df.resample('S').pad().assign(B=df.resample('S').interpolate().B)
Out[96]:
A B C
DATE_TIME
2016-10-08 13:57:00 in 5.610000 0
2016-10-08 13:57:01 in 5.618133 0
2016-10-08 13:57:02 in 5.626267 0
2016-10-08 13:57:03 in 5.634400 0
2016-10-08 13:57:04 in 5.642533 0
2016-10-08 13:57:05 in 5.650667 0
2016-10-08 13:57:06 in 5.658800 0
2016-10-08 13:57:07 in 5.666933 0
2016-10-08 13:57:08 in 5.675067 0
2016-10-08 13:57:09 in 5.683200 0
2016-10-08 13:57:10 in 5.691333 0
2016-10-08 13:57:11 in 5.699467 0
2016-10-08 13:57:12 in 5.707600 0
2016-10-08 13:57:13 in 5.715733 0
2016-10-08 13:57:14 in 5.723867 0
2016-10-08 13:57:15 in 5.732000 0
2016-10-08 13:57:16 in 5.740133 0
2016-10-08 13:57:17 in 5.748267 0
2016-10-08 13:57:18 in 5.756400 0
2016-10-08 13:57:19 in 5.764533 0
2016-10-08 13:57:20 in 5.772667 0
2016-10-08 13:57:21 in 5.780800 0
2016-10-08 13:57:22 in 5.788933 0
2016-10-08 13:57:23 in 5.797067 0
2016-10-08 13:57:24 in 5.805200 0
2016-10-08 13:57:25 in 5.813333 0
2016-10-08 13:57:26 in 5.821467 0
2016-10-08 13:57:27 in 5.829600 0
... ... ... ..
或更快一点的版本(一个 resample()
调用而不是两个):
rsmpl = df.resample('S')
rsmpl.pad().assign(B=rsmpl.interpolate().B)
我有一个 df
类似于:
print(df)
A B C
DATE_TIME
2016-10-08 13:57:00 in 5.61 0
2016-10-08 14:02:00 in 8.05 0
2016-10-08 14:07:00 out 7.92 0
2016-10-08 14:12:00 in 7.98 1
2016-10-08 14:17:00 out 8.18 0
2016-10-08 14:22:00 out 7.59 0
print (df.dtypes)
A object
B float64
C int64
dtype: object
我想将此 df
重新采样为 1S 频率,以便我可以将它与另一个 df
连接起来。
我无法解决的问题是,对于 object
和 int64
类型的列,我希望为新创建的时间行重复相同的值,这可以通过此函数完成:
df=df.resample('S', fill_method='pad')
而对于 float64
列,我正在寻找这个:
df=df.interpolate()
我考虑过应用 IF 语句,但我也认为我首先必须在插值步骤之前执行重采样步骤。当我仅按 df=df.resample('S')
重新采样时,我可以在之后进行插值,这适用于 float64
列但不适用于 object
和 Int64
列。
有人可以帮我吗?谢谢。
这是一个使用reindex
的方法:
index = pd.date_range(df.index[0], df.index[-1], freq="s")
df2 = df.reindex(index)
for col, s in df2.iteritems():
if s.dtype == float:
s.interpolate(inplace=True)
else:
s.ffill(inplace=True)
更新: 我认为你仍然可以使用矢量化方法(而不是循环遍历你的数据框),即使你有多个 float
列 - 它应该很多更快:
假设您有以下 DF(列:['B','D']
属于 float
dtype):
In [18]: df
Out[18]:
A B C D
DATE_TIME
2016-10-08 13:57:00 in 5.61 0 6.2271
2016-10-08 14:02:00 in 8.05 0 8.9355
2016-10-08 14:07:00 out 7.92 0 8.7912
2016-10-08 14:12:00 in 7.98 1 8.8578
2016-10-08 14:17:00 out 8.18 0 9.0798
2016-10-08 14:22:00 out 7.59 0 8.4249
In [19]: df.dtypes
Out[19]:
A object
B float64
C int64
D float64
dtype: object
您可以执行以下操作(它适用于 pandas 版本:0.18.0+):
rsmpl = df.resample('S')
pd.concat([rsmpl.pad()[df.select_dtypes(exclude=['float']).columns],
rsmpl.interpolate()[df.select_dtypes(include=['float']).columns]],
axis=1)
示例:
In [23]: pd.concat([rsmpl.pad()[df.select_dtypes(exclude=['float']).columns],
....: rsmpl.interpolate()[df.select_dtypes(include=['float']).columns]],
....: axis=1).head()
Out[23]:
A C B D
DATE_TIME
2016-10-08 13:57:00 in 0 5.610000 6.227100
2016-10-08 13:57:01 in 0 5.618133 6.236128
2016-10-08 13:57:02 in 0 5.626267 6.245156
2016-10-08 13:57:03 in 0 5.634400 6.254184
2016-10-08 13:57:04 in 0 5.642533 6.263212
旧答案:
您可以先 resample('S')
和 pad()
,然后将 float64
列 B
重新分配给 df.resample('S').interpolate().B
:
In [96]: df.resample('S').pad().assign(B=df.resample('S').interpolate().B)
Out[96]:
A B C
DATE_TIME
2016-10-08 13:57:00 in 5.610000 0
2016-10-08 13:57:01 in 5.618133 0
2016-10-08 13:57:02 in 5.626267 0
2016-10-08 13:57:03 in 5.634400 0
2016-10-08 13:57:04 in 5.642533 0
2016-10-08 13:57:05 in 5.650667 0
2016-10-08 13:57:06 in 5.658800 0
2016-10-08 13:57:07 in 5.666933 0
2016-10-08 13:57:08 in 5.675067 0
2016-10-08 13:57:09 in 5.683200 0
2016-10-08 13:57:10 in 5.691333 0
2016-10-08 13:57:11 in 5.699467 0
2016-10-08 13:57:12 in 5.707600 0
2016-10-08 13:57:13 in 5.715733 0
2016-10-08 13:57:14 in 5.723867 0
2016-10-08 13:57:15 in 5.732000 0
2016-10-08 13:57:16 in 5.740133 0
2016-10-08 13:57:17 in 5.748267 0
2016-10-08 13:57:18 in 5.756400 0
2016-10-08 13:57:19 in 5.764533 0
2016-10-08 13:57:20 in 5.772667 0
2016-10-08 13:57:21 in 5.780800 0
2016-10-08 13:57:22 in 5.788933 0
2016-10-08 13:57:23 in 5.797067 0
2016-10-08 13:57:24 in 5.805200 0
2016-10-08 13:57:25 in 5.813333 0
2016-10-08 13:57:26 in 5.821467 0
2016-10-08 13:57:27 in 5.829600 0
... ... ... ..
或更快一点的版本(一个 resample()
调用而不是两个):
rsmpl = df.resample('S')
rsmpl.pad().assign(B=rsmpl.interpolate().B)