2015-07-10 68 views
6

当使用大熊猫插值()填写NaN值是这样的:熊猫插值替换NaN的,但不是第一个数据点之前

In [1]: s = pandas.Series([np.nan, np.nan, 1, np.nan, 3, np.nan, np.nan]) 

In [2]: s.interpolate() 
Out[2]: 
0 NaN 
1 NaN 
2  1 
3  2 
4  3 
5  3 
6  3 
dtype: float64 

In [3]: pandas.version.version 
Out[3]: '0.16.2' 

,为什么熊猫在指数5替换值和6与3s,但保留在0和1的值?

我可以改变这种行为吗?我想离开指数5和6的NaN。

(实际上,我希望它线性外推以填充所有0,1,5和6,但这是一个不同的问题。红利点,如果你也回答它!)

回答

5

在内部,interpolate方法使用,其避免了填充传播大于特定的阈值以上的“限制”参数。

>>>df=pd.DataFrame([0, np.nan, np.nan, np.nan, np.nan,np.nan, 2]) 
>>>df 
df 
    0 
0 0 
1 NaN 
2 NaN 
3 NaN 
4 NaN 
5 NaN 
6 2 
>>>df.interpolate(limit=2) 
      0 
0 0.000000 
1 0.333333 
2 0.666667 
3  NaN 
4  NaN 
5  NaN 
6 2.000000 

默认情况下,限制适用于正向。在向后的方向上,默认限制被设置为零。这就是为什么你的第一步不是由方法填补。 可以使用'limit_direction'参数来改变方向。

df.interpolate(limit=2, limit_direction='backward') 
      0 
0 0.000000 
1  NaN 
2  NaN 
3  NaN 
4 1.333333 
5 1.666667 
6 2.000000 

填补了第一步,你的数据帧的最后一个步骤,可以应设置为“限制”和“limit_direction”到“两个”非零值:

>>> df=pd.DataFrame([ np.nan, np.nan, 0, np.nan, 2, np.nan,8,5,np.nan, np.nan]) 
>>> df 
    0 
0 NaN 
1 NaN 
2 0 
3 NaN 
4 2 
5 NaN 
6 8 
7 5 
8 NaN 
9 NaN 
>>> df.interpolate(method='spline', order=1, limit=10, limit_direction='both') 
      0 
0 -3.807382 
1 -2.083581 
2 0.000000 
3 1.364022 
4 2.000000 
5 4.811625 
6 8.000000 
7 5.000000 
8 4.937632 
9 4.138735 

的已讨论的主题here

+0

你认为在使用limit_direction ='both'(限制=无)并使用外推之间存在差异,就像在这里为instace所做的那样(https://stackoverflow.com/questions/22491628/extrapolate-values-in-pandas -dataframe)? –

2

interpolate行为在熊猫看起来很奇怪。您可以使用scipy.interpolate.interp1d来产生预期结果。对于线性外推,可以编写一个简单的函数来完成此任务。

import pandas as pd 
import numpy as np 
import scipy as sp 

s = pd.Series([np.nan, np.nan, 1, np.nan, 3, np.nan, np.nan]) 

# interpolate using scipy 
# =========================================== 
s_no_nan = s.dropna() 
func = sp.interpolate.interp1d(s_no_nan.index.values, s_no_nan.values, kind='linear', bounds_error=False) 
s_interpolated = pd.Series(func(s.index), index=s.index) 

Out[107]: 
0 NaN 
1 NaN 
2  1 
3  2 
4  3 
5 NaN 
6 NaN 
dtype: float64 

# extrapolate using user-defined func 
# =========================================== 
def my_extrapolate_func(scipy_interpolate_func, new_x): 
    x1, x2 = scipy_interpolate_func.x[0], scipy_interpolate_func.x[-1] 
    y1, y2 = scipy_interpolate_func.y[0], scipy_interpolate_func.y[-1] 
    slope = (y2 - y1)/(x2 - x1) 
    return y1 + slope * (new_x - x1) 

s_extrapolated = pd.Series(my_extrapolate_func(func, s.index.values), index=s.index) 

Out[108]: 
0 -1 
1 0 
2 1 
3 2 
4 3 
5 4 
6 5 
dtype: float64 
+0

谢谢。我仍然希望有人会回答熊猫发生的事情。它应该只是包装scipy ... – foobarbecue

+0

包装scipy将意味着熊猫有依赖于scipy,我想他们想避免。 – Jezzamon

+0

@foobarbecue你有没有想过这个?我得到类似的问题熊猫0.18.1 – toasteez