首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >DataFrame.interpolate()对尾随丢失的数据进行外推

DataFrame.interpolate()对尾随丢失的数据进行外推
EN

Stack Overflow用户
提问于 2014-08-12 11:01:12
回答 3查看 3.9K关注 0票数 13

考虑以下示例,在该示例中,我们设置一个样本数据集,创建一个MultiIndex,拆分数据帧,然后执行线性插值,其中我们逐行填充:

代码语言:javascript
复制
import pandas as pd  # version 0.14.1
import numpy as np  # version 1.8.1

df = pd.DataFrame({'location': ['a', 'b'] * 5,
                   'trees': ['oaks', 'maples'] * 5,
                   'year': range(2000, 2005) * 2,
                   'value': [np.NaN, 1, np.NaN, 3, 2, np.NaN, 5, np.NaN, np.NaN, np.NaN]})
df.set_index(['trees', 'location', 'year'], inplace=True)
df = df.unstack()
df = df.interpolate(method='linear', axis=1)

其中未堆叠的数据集如下所示:

代码语言:javascript
复制
                 value                        
year              2000  2001  2002  2003  2004
trees  location                               
maples b           NaN     1   NaN     3   NaN
oaks   a           NaN     5   NaN   NaN     2

作为一种插值方法,我期望得到以下输出:

代码语言:javascript
复制
                 value                        
year              2000  2001  2002  2003  2004
trees  location                               
maples b           NaN     1     2     3   NaN
oaks   a           NaN     5     4     3     2

但是相反,该方法会产生(请注意外推值):

代码语言:javascript
复制
                 value                        
year              2000  2001  2002  2003  2004
trees  location                               
maples b           NaN     1     2     3     3
oaks   a           NaN     5     4     3     2

有没有办法指示熊猫不要在序列中的最后一个非缺失值之后进行推断?

编辑:

我仍然希望在pandas中看到这个功能,但是现在我已经在numpy中将其实现为一个函数,然后我使用df.apply()来修改df。我在pandas中错过的是np.interp()中的leftright参数的功能。

代码语言:javascript
复制
def interpolate(a, dec=None):
    """
    :param a: a 1d array to be interpolated
    :param dec: the number of decimal places with which each
                value should be returned
    :return: returns an array of integers or floats
    """

    # default value is the largest number of decimal places in the input array
    if dec is None:
        dec = max_decimal(a)

    # detect array format convert to numpy as necessary
    if type(a) == list:
        t = 'list'
        b = np.asarray(a, dtype='float')
    if type(a) in [pd.Series, np.ndarray]:
        b = a

    # return the row if it's all nan's
    if np.all(np.isnan(b)):
        return a

    # interpolate
    x = np.arange(b.size)
    xp = np.where(~np.isnan(b))[0]
    fp = b[xp]
    interp = np.around(np.interp(x, xp, fp, np.nan, np.nan), decimals=dec)

    # return with proper numerical type formatting
    # check to make sure there aren't nan's before converting to int
    if dec == 0 and np.isnan(np.sum(interp)) == False:
        interp = interp.astype(int)
    if t == 'list':
        return interp.tolist()
    else:
        return interp


# two little helper functions
def count_decimal(i):
    try:
        return int(decimal.Decimal(str(i)).as_tuple().exponent) * -1
    except ValueError:
        return 0


def max_decimal(a):
    m = 0
    for i in a:
        n = count_decimal(i)
        if n > m:
            m = n
    return m

在示例数据集上的效果非常出色:

代码语言:javascript
复制
In[1]: df.apply(interpolate, axis=1)
Out[1]:
                 value                        
year              2000  2001  2002  2003  2004
trees  location                               
maples b           NaN     1     2     3   NaN
oaks   a           NaN     5     4     3     2
EN

回答 3

Stack Overflow用户

发布于 2015-10-28 20:17:56

替换以下行:

代码语言:javascript
复制
df = df.interpolate(method='linear', axis=1)

有了这个:

代码语言:javascript
复制
df = df.interpolate(axis=1).where(df.bfill(axis=1).notnull())

它通过使用回填为拖尾NaNs找到一个掩码。

票数 6
EN

Stack Overflow用户

发布于 2019-02-21 04:32:16

从Pandas版本0.21.0开始,limit_area='inside' tellsdf.interpolate`仅填充由有效值包围的NaNs:

代码语言:javascript
复制
import pandas as pd  # version 0.21.0
import numpy as np  

df = pd.DataFrame({'location': ['a', 'b'] * 5,
                   'trees': ['oaks', 'maples'] * 5,
                   'year': list(range(2000, 2005)) * 2,
                   'value': [np.NaN, 1, np.NaN, 3, 2, np.NaN, 5, np.NaN, np.NaN, np.NaN]})
df.set_index(['trees', 'location', 'year'], inplace=True)
df = df.unstack()

df2 = df.interpolate(method='linear', axis=1, limit_area='inside')
print(df2)

收益率

代码语言:javascript
复制
                value                    
year             2000 2001 2002 2003 2004
trees  location                          
maples b          NaN  1.0  2.0  3.0  NaN
oaks   a          NaN  5.0  4.0  3.0  2.0
票数 2
EN

Stack Overflow用户

发布于 2015-03-20 02:13:56

这是一个更紧凑的解决方案,可以在初始插值之后应用。

代码语言:javascript
复制
def de_extrapolate(row):  
    extrap = row[row==row[-1]]    
    if extrap.size > 1:
        first_index = extrap.index[1]
        row[first_index:] = np.nan
    return row

和以前一样,我们有:

代码语言:javascript
复制
In [1]: df.interpolate(axis=1).apply(de_extrapolate, axis=1)
Out[1]: 
                value                    
year             2000 2001 2002 2003 2004
trees  location                          
maples b          NaN    1    2    3  NaN
oaks   a          NaN    5    4    3    2
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25255496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档