pandas插值与最接近的非数字值

时间:2017-04-24 10:46:10

标签: python-3.x pandas datetime

我有一个带有数字和非数字值的数据框,其中包含日期时间索引:

df = pd.DataFrame([
    {'date': datetime(2017, 4, 24, 1), 'a':1, 'b':2, 'c': "hee"},
    {'date': datetime(2017, 4, 24, 2), 'a':2, 'b':4, 'c': 'hoo'},
    {'date': datetime(2017, 4, 24, 3), 'a':4, 'b':8, 'c': 'joo'},
    {'date': datetime(2017, 4, 24, 4), 'a':8, 'b':16, 'c': 'jee'}
]).set_index('date')

我想:

  • 线性插值数值;和
  • 获取非数字值的最接近值。

最优雅的实施是什么?

策略1

插值全部,然后fillna

df = df.resample('20T').interpolate('linear')
df.fillna(method='nearest')

但是...... nearest方法没有实现。

策略2

拆分数字和非数字列

df2 = df.resample('20T')
df_a = df2._get_numeric_data().interpolate('linear')
df_b = df2[list(set(df.columns) - set(set(df_a.columns)))].interpolate('nearest')

给出错误:

  

TypeError:无法插入所有NaN。

更新

使用最近的方法进行插值,适用于布尔值和数值,但不适用于字符串,例如:

df.resample('20T').intepolate('nearest')

2 个答案:

答案 0 :(得分:1)

这就是你想要的吗?

Route::get('/allo', function () {
    return date("Y-m-d h:i:sa")."Allo Allo";
});

答案 1 :(得分:0)

由于interpolate("nearest")适用于数字类型,因此解决方案是:

  1. 将列从字符串转换为分类(数字)
  2. 使用interpolate("nearest")
  3. 插入类别
  4. 映射回字符串内插的分类列

    def fillna_nearest(series):
        fact = series.astype('category').factorize()
    
        series_cat = pd.Series(fact[0]).replace(-1, np.nan) # get string as categorical (-1 is NaN)
        series_cat_interp = series_cat.interpolate("nearest") # interpolate categorical
    
        cat_to_string = {i:x for i,x in enumerate(fact[1])} # dict connecting category to string
        series_str_interp = series_cat_interp.map(cat_to_string) # turn category back to string
    
        return series_str_interp
    
    
    In [10]: df.resample('20T').interpolate().apply(fillna_nearest)
    Out[10]: 
              a          b    c
    0  1.000000   2.000000  hee
    1  1.333333   2.666667  hee
    2  1.666667   3.333333  hoo
    3  2.000000   4.000000  hoo
    4  2.666667   5.333333  hoo
    5  3.333333   6.666667  joo
    6  4.000000   8.000000  joo
    7  5.333333  10.666667  joo
    8  6.666667  13.333333  jee
    9  8.000000  16.000000  jee