针对 float64 与 object 和 int64 列对具有不同条件的时间序列进行上采样

Posted

技术标签:

【中文标题】针对 float64 与 object 和 int64 列对具有不同条件的时间序列进行上采样【英文标题】:Upsampling a time-series with different conditions for float64 vs object and int64 columns 【发布时间】:2017-01-03 17:20:58 【问题描述】:

我有一个类似这样的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 列。 有人可以帮我吗?谢谢。

【问题讨论】:

【参考方案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)

【讨论】:

【参考方案2】:

更新:我认为您仍然可以使用矢量化方法(而不是循环遍历您的数据框),即使您有多个 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() 然后用df.resample('S').interpolate().B 重新分配float64B

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,它有更多的列,而不必单独指定它们。注意:我必须将代码调整为df.resample('S', fill_method='pad').assign(B=df.resample('S').interpolate().B),否则我会收到错误消息`AttributeError: 'DataFrame' object has no attribute 'pad'`。我不知道如何修改更快的版本以不收到该错误消息。非常感谢你们! @vera,从 pandas 0.18.0 开始,重采样 API has been changed - 很可能您使用的是旧版 pandas。 @vera,我已经更新了我的答案 - 现在它将处理多个 float 列,并且仍将使用矢量化方法 酷,谢谢!该解决方案看起来更简单,我真的很想测试它。我仍在阅读如何在 Spyder(Python 3.5)上更新我的 pandas 版本(0.17.0)。我尝试使用`conda update pandas` ...它不起作用,当我输入help(conda) 时,它显示NameError: name 'conda' is not defined。我觉得我在这里缺少一些基础知识.....

以上是关于针对 float64 与 object 和 int64 列对具有不同条件的时间序列进行上采样的主要内容,如果未能解决你的问题,请参考以下文章

关于float在32位和64位的转换?

在C#中long与int64有啥区别吗

float vs double

为啥 GOlang的float型后面要加32或64?

[ROS-Beginner]10.创建一个ROS msg和srv

go笔记 - 字符串、数字、byte相互转换