对float64与object和int64列的不同条件进行上采样

时间:2016-08-27 00:42:41

标签: pandas time-series interpolation resampling

我有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列。 请问有人帮帮我吗?谢谢。

2 个答案:

答案 0 :(得分:1)

以下是使用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)

答案 1 :(得分:1)

更新:我认为您仍然可以使用矢量化方法(不会遍历数据框),即使您有多个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

OLD回答:

您可以先resample('S')pad(),然后使用float64重新分配Bdf.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)