对 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 连接起来。 我无法解决的问题是,对于 objectint64 类型的列,我希望为新创建的时间行重复相同的值,这可以通过此函数完成:

df=df.resample('S', fill_method='pad')

而对于 float64 列,我正在寻找这个:

df=df.interpolate()

我考虑过应用 IF 语句,但我也认为我首先必须在插值步骤之前执行重采样步骤。当我仅按 df=df.resample('S') 重新采样时,我可以在之后进行插值,这适用于 float64 列但不适用于 objectInt64 列。 有人可以帮我吗?谢谢。

这是一个使用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(),然后将 float64B 重新分配给 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)