使用带有浮点数的 pandas reindex:插值
Posted
技术标签:
【中文标题】使用带有浮点数的 pandas reindex:插值【英文标题】:Using pandas reindex with floats: interpolation 【发布时间】:2013-06-25 10:21:36 【问题描述】:你能解释一下这种奇怪的行为吗?
df=pd.DataFrame('year':[1986,1987,1988],'bomb':arange(3)).set_index('year')
In [9]: df.reindex(arange(1986,1988.125,.125))
Out[9]:
bomb
1986.000 0
1986.125 NaN
1986.250 NaN
1986.375 NaN
1986.500 NaN
1986.625 NaN
1986.750 NaN
1986.875 NaN
1987.000 1
1987.125 NaN
1987.250 NaN
1987.375 NaN
1987.500 NaN
1987.625 NaN
1987.750 NaN
1987.875 NaN
1988.000 2
In [10]: df.reindex(arange(1986,1988.1,.1))
Out[10]:
bomb
1986.0 0
1986.1 NaN
1986.2 NaN
1986.3 NaN
1986.4 NaN
1986.5 NaN
1986.6 NaN
1986.7 NaN
1986.8 NaN
1986.9 NaN
1987.0 NaN
1987.1 NaN
1987.2 NaN
1987.3 NaN
1987.4 NaN
1987.5 NaN
1987.6 NaN
1987.7 NaN
1987.8 NaN
1987.9 NaN
1988.0 NaN
当增量不是 .125 时,我发现新索引值不会“找到”具有匹配值的旧行。即有一个精度问题没有被克服。即使我在尝试插值之前强制索引为浮点数也是如此。发生了什么和/或这样做的正确方法是什么? 通过使用
,我已经能够让它以 0.1 的增量工作reindex( np.array(map(round,arange(1985,2010+dt,dt)*10))/10.0 )
顺便说一句,我这样做是线性插值多个列的第一步(例如,“炸弹”就是其中之一)。如果有更好的方法可以做到这一点,我很乐意直截了当。
【问题讨论】:
看起来你真的想要一个类似日期的索引,或者你真的出于某种原因想要一个浮点索引?你想要什么作为你的最终输出? 是的,我猜它是 datelike,但我真的不需要特殊/聪明的功能,除了小数点后。最终输出?这是:youtube.com/watch?v=1BGzzykW_QM&feature=youtu.be 即我有几年的数据,我想将列值插入到(更精细的)网格中以便平滑地制作动画。 【参考方案1】:你得到你想要的。 reindex 方法仅尝试将数据放到您提供的新索引上。如 cmets 中所述,您可能正在索引中寻找日期。我猜你希望 reindex 方法可以做到这一点(插值):
df2 =df.reindex(arange(1986,1988.125,.125))
pd.Series.interpolate(df2['bomb'])
1986.000 0.000
1986.125 0.125
1986.250 0.250
1986.375 0.375
1986.500 0.500
1986.625 0.625
1986.750 0.750
1986.875 0.875
1987.000 1.000
1987.125 1.125
1987.250 1.250
1987.375 1.375
1987.500 1.500
1987.625 1.625
1987.750 1.750
1987.875 1.875
1988.000 2.000
Name: bomb
您使用的第二个示例是不一致可能是因为浮点精度。步进 0.125 等于 1/8,这可以精确地以二进制形式完成。步长 0.1 不能直接映射到二进制,因此 1987 年可能只差一小部分。
1987.0 == 1987.0000000001
False
【讨论】:
谢谢。不,我没想到重新索引会进行插值。正如我所说,这是插值的第一步/设置。 “可以完全以二进制形式完成的 1/8”是我缺少的主要见解。但我仍然没有看到我得到了我要求的东西。尤其是当示例失败时,即使索引是浮点数。 见这里:pandas.pydata.org/pandas-docs/dev/…,浮动索引几乎总是一个坏主意;因为您永远无法精确匹配所有浮点数,所以您有问题;要么使用日期时间,例如索引 int 索引,要么使用多个列,甚至是字符串索引【参考方案2】:我认为你最好使用 PeriodIndex 来做这样的事情
In [39]: df=pd.DataFrame('bomb':np.arange(3))
In [40]: df
Out[40]:
bomb
0 0
1 1
2 2
In [41]: df.index = pd.period_range('1986','1988',freq='Y').asfreq('M')
In [42]: df
Out[42]:
bomb
1986-12 0
1987-12 1
1988-12 2
In [43]: df = df.reindex(pd.period_range('1986','1988',freq='M'))
In [44]: df
Out[44]:
bomb
1986-01 NaN
1986-02 NaN
1986-03 NaN
1986-04 NaN
1986-05 NaN
1986-06 NaN
1986-07 NaN
1986-08 NaN
1986-09 NaN
1986-10 NaN
1986-11 NaN
1986-12 0
1987-01 NaN
1987-02 NaN
1987-03 NaN
1987-04 NaN
1987-05 NaN
1987-06 NaN
1987-07 NaN
1987-08 NaN
1987-09 NaN
1987-10 NaN
1987-11 NaN
1987-12 1
1988-01 NaN
In [45]: df.iloc[0,0] = -1
In [46]: df['interp'] = df['bomb'].interpolate()
In [47]: df
Out[47]:
bomb interp
1986-01 -1 -1.000000
1986-02 NaN -0.909091
1986-03 NaN -0.818182
1986-04 NaN -0.727273
1986-05 NaN -0.636364
1986-06 NaN -0.545455
1986-07 NaN -0.454545
1986-08 NaN -0.363636
1986-09 NaN -0.272727
1986-10 NaN -0.181818
1986-11 NaN -0.090909
1986-12 0 0.000000
1987-01 NaN 0.083333
1987-02 NaN 0.166667
1987-03 NaN 0.250000
1987-04 NaN 0.333333
1987-05 NaN 0.416667
1987-06 NaN 0.500000
1987-07 NaN 0.583333
1987-08 NaN 0.666667
1987-09 NaN 0.750000
1987-10 NaN 0.833333
1987-11 NaN 0.916667
1987-12 1 1.000000
1988-01 NaN 1.000000
【讨论】:
以上是关于使用带有浮点数的 pandas reindex:插值的主要内容,如果未能解决你的问题,请参考以下文章
pandas dataframe 如何把带有千位分隔符的字符串转化为浮点数
如何使用 fill_value 对 Pandas 中的 TimeSeries 重新采样?
Python - 使用 Pandas 消除大括号和输出浮点数