使用数字索引对pandas系列进行重采样

7 投票
3 回答
5352 浏览
提问于 2025-04-17 20:49

假设我有一个 pandas.Series,它的索引是数字类型,比如:

pd.Series( [10,20], [1.1, 2.3] )

我该如何将这个序列按 0.1 的间隔重新取样呢?我发现 .resample 函数似乎只适用于日期时间的间隔?

3 个回答

0

我觉得你不能用非整数的索引,因为浮点数比较会有问题。不过,如果你想用0.1这样的数,可以试试下面的方法:

  • 先创建一个新的数据框 df = pd.DataFrame(index=range(100, 201)) [这里的数字代表的是0.1]
  • 把100(原本是10)和200(原本是20)的位置的值设置为1.1和2.3
  • 然后用 df.fillna(method='pad', inplace=True) 来填补空缺

另外,看起来你其实根本不需要用到索引,你只是想要数据之间的间隔而已……

1

一种选择是使用cut来对这些数据进行分箱处理(虽然这比重新采样要简单得多,但我还是试试):

In [11]: cat, retbins = pd.cut(s.index, np.arange(1, 3, 0.1), retbins=True)

In [12]: s.index = retbins[cat.labels]

In [13]: s
Out[13]: 
1.0    10
2.2    20
dtype: int64

假设你想用how='sum'来重新采样:

In [14]: s = s.groupby(s.index).sum()

In [15]: s = s.reindex(retbins)

现在有很多NaN(缺失值),你可以像Tom建议的那样,进行插值处理:

In [16]: s.interpolate()
7

这被称为插值。你可以把重采样看作插值的一种特殊情况。

In [24]: new_idx = s.index + pd.Index(np.arange(1.1, 2.3, .01))

In [25]: s.reindex(new_idx).interpolate().head()
Out[25]: 
1.10    10.000000
1.11    10.083333
1.12    10.166667
1.13    10.250000
1.14    10.333333
dtype: float64

In [26]: s.reindex(new_idx).interpolate().tail()
Out[26]: 
2.26    19.666667
2.27    19.750000
2.28    19.833333
2.29    19.916667
2.30    20.000000
dtype: float64

我们需要 new_idx 是原始索引和我们想要插值的值的结合,这样原始索引就不会丢失。

看看插值的方法: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.interpolate.html

撰写回答