Pandas Dataframe.Interpolate()为相同的索引日期提供不同的值

时间:2017-07-26 22:47:23

标签: python pandas interpolation

使用DataFrame

date_index  value
2013-01-01  0.50
2013-01-01  0.50
2013-01-01  0.50
2013-01-01  0.50
2013-01-02  1.50
2013-01-02  1.50
2013-01-02  1.50
2013-01-02  1.50
2013-01-03  0.98
2013-01-03  0.98
2013-01-03  0.98
2013-01-03  0.98
2013-01-04  NaN
2013-01-04  1.00
2013-01-04  NaN
2013-01-04  NaN
2013-01-05  1.90
2013-01-05  1.90
2013-01-05  1.90
2013-01-05  1.90
2013-01-06  2.50
2013-01-06  2.50
2013-01-06  2.50
2013-01-06  2.50
2013-01-07  2.89
2013-01-07  2.89
2013-01-07  2.89
2013-01-07  2.89
2013-01-08  NaN
2013-01-08  NaN
2013-01-08  NaN
2013-01-08  NaN
2013-01-09  3.90
2013-01-09  3.90
2013-01-09  3.90
2013-01-09  3.90
2013-01-10  5.00
2013-01-10  5.00
2013-01-10  5.00
2013-01-10  5.00

将上述内容复制到剪贴板

import pandas as pd
df = pd.read_clipboard()
df = df.set_index('date_index')

使用Interpolate填充nan

x = df.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction='both', downcast=None)

我原本期望插值考虑相同的x点,因此每个x的y值应相同。但事实并非如此。

有关nan的日期是2013-01-04和2013-01-08

之前

2013-01-04  NaN
2013-01-04  1.00
2013-01-04  NaN
2013-01-04  NaN
2013-01-08  NaN
2013-01-08  NaN 
2013-01-08  NaN
2013-01-08  NaN

2013-01-04  0.990
2013-01-04  1.000
2013-01-04  1.300
2013-01-04  1.600
2013-01-08  3.092
2013-01-08  3.294
2013-01-08  3.496 
2013-01-08  3.698

我是否正确理解插值的使用?我期待

的结果
2013-01-04  1.000
2013-01-04  1.000
2013-01-04  1.000
2013-01-04  1.000
2013-01-08  3.945
2013-01-08  3.945
2013-01-08  3.945 
2013-01-08  3.945

3 个答案:

答案 0 :(得分:3)

根据文件:

  

'linear':忽略索引并将值视为等间距。   默认

如果您想在考虑日期的情况下获得结果,可以选择“时间”或“索引”等方法

答案 1 :(得分:1)

问题在于您可能会复制索引值,因此插值方法认为这些是执行线性插值的附加步骤。因此,不是从1到1.9,而是1 - > 1.3 - > 1.6 - > 1.9。

以下是一种解决方法,可以删除重复的索引条目:

df = pd.read_clipboard()
uniqDates = df['date_index'].unique()
df = df.set_index('date_index')
df2 = df.dropna()
df2 = df2[-df2.index.duplicated()]
df2 = df2.reindex(uniqDates)
df2 = df2.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction='both', downcast=None)
interpDict = df2['value'].to_dict()
df['value'] = [interpDict[x] for x in df.index]

<强>替代地

您可以将索引值强制转换为datetime对象,然后使用method='time'插值:

df = pd.read_clipboard()
df['date_index'] = pd.to_datetime(df['date_index'])
df = df.set_index('date_index')
x = df.interpolate(method='time')
x.index = [x.strftime('%Y-%m-%d') for x in x.index]

答案 2 :(得分:1)

根据the Series.interpolate() documentationmethod='linear' kwarg意味着pandas将忽略索引并假设值是均匀间隔的系列。我建议您将索引转换为DatetimeIndex并将method='time'传递给该系列。

df.index = pd.to_datetime(df.index)
x = df.interpolate(method='time', axis=0, limit=None, inplace=False, limit_direction='both', downcast=None)

<强>后

            value
date_index       
2013-01-04  1.000
2013-01-04  1.000
2013-01-04  1.000
2013-01-04  1.000
2013-01-08  3.395
2013-01-08  3.395
2013-01-08  3.395
2013-01-08  3.395