熊猫resample()系列给出错误的索引

时间:2019-07-10 16:26:45

标签: python-3.x pandas time-series

我正在尝试将日期和浮点值的多年时间序列归类。我试图将每天汇总到15分钟的垃圾箱中。因此,我按天对数据集进行分组,然后每天以15分钟为增量重新采样。

结果似乎很奇怪,所以我仔细研究了重采样的行为。下面的代码总结了我观察到的结果类型(我在repl.it中运行)

aindex = pd.to_datetime([
"2013-04-05 04:15:31",
"2013-04-05 05:15:18",
"2013-04-05 05:15:19",
"2013-04-05 05:15:19",
"2013-04-05 05:17:15",
"2013-04-05 07:06:31",
"2013-04-09 04:15:31",
"2013-04-09 05:15:18",
"2013-04-09 05:15:19",
"2013-04-09 05:15:19",
"2013-04-09 05:17:15",
"2013-04-09 07:06:31",
"2013-04-09 07:21:28",
"2013-04-09 09:18:19",
"2013-04-09 09:19:19",
"2013-04-09 09:21:31"])
a = pd.Series([-4.50e+08,
-4.80e+08,
-6.10e+08,
-5.80e+08,
-5.70e+08,
-5.710e+08,
-4.598432e+08,
-4.814140e+08,
-6.109284e+08,
-5.870819e+08,
-5.759888e+08,
-5.713363e+08,
-5.275122e+07,
-2.853787e+08,
-2.523782e+08,
-4.273267e+08],aindex)
print(a)
print(a.groupby(a.index).apply(lambda x: x))
print(a.resample("15T", base=0).apply(lambda x: x))
print(a.groupby(a.index).resample("15T").apply(lambda x: x))

“ groupby”的行为符合预期,但请注意,“ x”的每个值均为pd.Series类型。 'resample'还返回pd.Series类型,但是当我在repl.it或Jupyter中显示它时似乎会丢失值,但是如果将.apply(lambda x:x)更改为.apply(lambda x:list(x)),则可以看到实际上有多个值。 'groupby'+'resample'几乎达到了我的预期。每天都有15分钟的时段,除了在任何“重采样”返回多个值的地方索引出错之外。

我试图了解自己所看到的内容,因此我可以放心地应用该过程。这是正确的行为吗?如果是,为什么?

注意:为了进一步阐明我的期望。如果我查看一天的重新采样结果,则重新采样包括空箱:

2013-04-05 04:15:00   -450000000.0
2013-04-05 04:30:00            NaN
2013-04-05 04:45:00            NaN
2013-04-05 05:00:00            NaN
2013-04-05 05:15:00   -570000000.0
2013-04-05 05:30:00            NaN
2013-04-05 05:45:00            NaN
2013-04-05 06:00:00            NaN
2013-04-05 06:15:00            NaN
2013-04-05 06:30:00            NaN
2013-04-05 06:45:00            NaN
2013-04-05 07:00:00   -571000000.0
2013-04-05 07:15:00            NaN
2013-04-05 07:30:00            NaN
2013-04-05 07:45:00            NaN
2013-04-05 08:00:00            NaN
2013-04-05 08:15:00            NaN
2013-04-05 08:30:00            NaN
2013-04-05 08:45:00            NaN
2013-04-05 09:00:00            NaN
2013-04-05 09:15:00            NaN
2013-04-05 09:30:00            NaN
2013-04-05 09:45:00            NaN
2013-04-05 10:00:00            NaN

但是如果首先完成groupby,我不会得到空的垃圾箱。为什么不呢?:

...
2013-04-05 04:15:31  2013-04-05 04:15:00   -450000000.0
2013-04-05 05:15:18  2013-04-05 05:15:00   -480000000.0
2013-04-05 05:15:19  2013-04-05 05:15:00   -580000000.0
2013-04-05 05:17:15  2013-04-05 05:15:00   -570000000.0
2013-04-05 07:06:31  2013-04-05 07:00:00   -571000000.0
...

1 个答案:

答案 0 :(得分:1)

重采样是一个棘手的功能。重采样的主要问题是您需要选择要保留的值(使用pandas.DataFrame.lastpandas.DataFrame.first)。

这样做:

> a.resample("15T", base=0).last()

2013-04-05 04:15:00   -450000000.0
2013-04-05 04:30:00            NaN
2013-04-05 04:45:00            NaN
2013-04-05 05:00:00            NaN
2013-04-05 05:15:00   -570000000.0

将无需使用.apply(lambda x: x),因为它将保留样本中的最后一个元素。

pandas.DataFrame重采样已使用mean作为默认值。

要与groupby等价,您需要做的是比较安全的分组,然后应用均值,以便我们可以对区间的值进行插值

> a.groupby(a.index).mean().resample("15T", base=0).last()


2013-04-05 04:15:00   -450000000.0
2013-04-05 04:30:00            NaN
2013-04-05 04:45:00            NaN
2013-04-05 05:00:00            NaN
2013-04-05 05:15:00   -570000000.0

希望您能正确理解您的问题。让我知道是否有帮助。

修改

您可以尝试使用以下方法保留所有索引:

> a.resample('15T').asfreq()    

但是您会得到:ValueError: cannot reindex from a duplicate axis

这是主要问题,不能复制大熊猫中的索引。这就是为什么groupby用均值起作用的原因,因为它将项按一个元素分组,然后对该组重新采样。

在没有groupby的情况下实现此目标的一种方法是使用Multiindex数据帧:

> a.to_frame().set_index([a.index, a.index.round('15T')])

                                                   0
2013-04-05 04:15:31 2013-04-05 04:15:00 -450000000.0
2013-04-05 05:15:18 2013-04-05 05:15:00 -480000000.0
2013-04-05 05:15:19 2013-04-05 05:15:00 -610000000.0
                    2013-04-05 05:15:00 -580000000.0
2013-04-05 05:17:15 2013-04-05 05:15:00 -570000000.0
2013-04-05 07:06:31 2013-04-05 07:00:00 -571000000.0
2013-04-09 04:15:31 2013-04-09 04:15:00 -459843200.0
2013-04-09 05:15:18 2013-04-09 05:15:00 -481414000.0
2013-04-09 05:15:19 2013-04-09 05:15:00 -610928400.0
                    2013-04-09 05:15:00 -587081900.0
2013-04-09 05:17:15 2013-04-09 05:15:00 -575988800.0
2013-04-09 07:06:31 2013-04-09 07:00:00 -571336300.0
2013-04-09 07:21:28 2013-04-09 07:15:00  -52751220.0
2013-04-09 09:18:19 2013-04-09 09:15:00 -285378700.0
2013-04-09 09:19:19 2013-04-09 09:15:00 -252378200.0
2013-04-09 09:21:31 2013-04-09 09:15:00 -427326700.0

或者,更改索引顺序以按舍入索引分组:

> a.to_frame().set_index([a.index.round('15T'), a.index])


2013-04-05 04:15:00 2013-04-05 04:15:31 -450000000.0
2013-04-05 05:15:00 2013-04-05 05:15:18 -480000000.0
                    2013-04-05 05:15:19 -610000000.0
                    2013-04-05 05:15:19 -580000000.0
                    2013-04-05 05:17:15 -570000000.0
2013-04-05 07:00:00 2013-04-05 07:06:31 -571000000.0
2013-04-09 04:15:00 2013-04-09 04:15:31 -459843200.0
2013-04-09 05:15:00 2013-04-09 05:15:18 -481414000.0
                    2013-04-09 05:15:19 -610928400.0
                    2013-04-09 05:15:19 -587081900.0
                    2013-04-09 05:17:15 -575988800.0
2013-04-09 07:00:00 2013-04-09 07:06:31 -571336300.0
2013-04-09 07:15:00 2013-04-09 07:21:28  -52751220.0
2013-04-09 09:15:00 2013-04-09 09:18:19 -285378700.0
                    2013-04-09 09:19:19 -252378200.0
                    2013-04-09 09:21:31 -427326700.0