将大型数据帧插值到稀疏的不规则索引上

时间:2013-08-01 18:44:10

标签: python pandas interpolation

我有一个数据帧,其中包含以30分钟间隔采样的数年数据(来自连续水质传感器的7个参数),并且我有另一个数据帧包含几百个随机时间点的数据,其中一个精确度。我想在几百个随机时间点找到7个参数的插值。

所以这里有几行数据框的样子:

print df1    
                    Temp  SpCond   Sal  DO_pct  DO_mgl  Depth   pH  Turb
2002-07-16 14:00:00  26.0   45.31  29.3    71.6     4.9   0.95  7.9    -5
2002-07-16 14:30:00  25.9   45.22  29.2    70.4     4.9   0.98  7.9    -6
2002-07-16 15:00:00  26.0   44.92  29.0    76.2     5.3   1.02  7.9    -6
2002-07-16 15:30:00  26.0   45.06  29.1    77.9     5.4   1.06  7.9    -5
2002-07-16 16:00:00  25.9   45.23  29.2    67.0     4.6   1.11  7.8    -6
2002-07-16 16:30:00  25.9   45.33  29.3    72.9     5.0   1.17  7.9    -6
2002-07-16 17:00:00  25.9   45.46  29.4    65.8     4.5   1.21  7.9    -6
2002-07-16 17:30:00  25.9   45.40  29.4    70.5     4.9   1.19  7.9    -6
2002-07-16 18:00:00  25.9   45.27  29.3    74.3     5.1   1.15  7.9    -6
2002-07-16 18:30:00  25.8   45.57  29.5    67.6     4.7   1.11  7.8    -6
...

print df2
                      PO4F   NH4F   NO2F   NO3F  NO23F  CHLA_N
DateTimeStamp                                                 
2002-07-16 14:01:00  0.053  0.073  0.005  0.021  0.026     8.6
2002-07-16 16:05:00  0.029  0.069  0.002  0.016  0.018     9.6
2002-07-16 18:09:00  0.023  0.073  0.000    NaN  0.014     5.8
...

我想在df2的索引值处找到df1的值,但是我能从读取文档和其他stackoverflow答案中找到的唯一方法是将df1放在一分钟的时间基础上(这将产生一堆nans),然后使用Series.interpolate填充nans,然后在df2的离散时间拉出一分钟值。这似乎非常浪费。必须有另一种方式,对吧?

2 个答案:

答案 0 :(得分:1)

如果你想要插值,我认为你坚持使用你描述的方法,或者大概是“浪费”的东西。如果您可以设置获取最新值或下一个值,请分别使用ffillbfill

In [34]: df1.reindex(df2.index, method='ffill')
Out[34]: 
                     Temp  SpCond   Sal  DO_pct  DO_mgl  Depth   pH  Turb
DateTimeStamp                                                            
2002-07-16 14:01:00  26.0   45.31  29.3    71.6     4.9   0.95  7.9    -5
2002-07-16 16:05:00  25.9   45.23  29.2    67.0     4.6   1.11  7.8    -6
2002-07-16 18:09:00  25.9   45.27  29.3    74.3     5.1   1.15  7.9    -6

答案 1 :(得分:1)

这是一种做我认为你想要的方式

开始帧df1和df2

In [100]: df1
Out[100]: 
                     Temp  SpCond   Sal  DO_pct  DO_mgl  Depth   pH  Turb
time                                                                     
2002-07-16 14:00:00  26.0   45.31  29.3    71.6     4.9   0.95  7.9    -5
2002-07-16 14:30:00  25.9   45.22  29.2    70.4     4.9   0.98  7.9    -6
2002-07-16 15:00:00  26.0   44.92  29.0    76.2     5.3   1.02  7.9    -6
2002-07-16 15:30:00  26.0   45.06  29.1    77.9     5.4   1.06  7.9    -5
2002-07-16 16:00:00  25.9   45.23  29.2    67.0     4.6   1.11  7.8    -6
2002-07-16 16:30:00  25.9   45.33  29.3    72.9     5.0   1.17  7.9    -6
2002-07-16 17:00:00  25.9   45.46  29.4    65.8     4.5   1.21  7.9    -6
2002-07-16 17:30:00  25.9   45.40  29.4    70.5     4.9   1.19  7.9    -6
2002-07-16 18:00:00  25.9   45.27  29.3    74.3     5.1   1.15  7.9    -6
2002-07-16 18:30:00  25.8   45.57  29.5    67.6     4.7   1.11  7.8    -6

In [101]: df2
Out[101]: 
                      P04F   NH4F   N02F   N03F  NO23F  CHLA_N
time                                                          
2002-07-16 14:01:00  0.053  0.073  0.005  0.021  0.026     8.6
2002-07-16 16:05:00  0.029  0.069  0.002  0.016  0.018     9.6
2002-07-16 18:09:00  0.023  0.073  0.000    NaN  0.014     5.8

计算舍入时间(我以纳秒为单位转换为int的时间,然后舍入到最接近的30 * 60秒)。如果你想要上升或下降(到下一个半小时),你可能需要调整

In [102]: new_index = pd.DatetimeIndex(int(1e9*30*60)*(np.round(df2.index.asi8/(1e9*30*60))).astype(np.int64)).values

In [104]: new_index
Out[104]: 
array(['2002-07-16T10:00:00.000000000-0400',
       '2002-07-16T12:00:00.000000000-0400',
       '2002-07-16T14:00:00.000000000-0400'], dtype='datetime64[ns]')

复制只是为了避免修改原始帧。设置新索引

In [105]: df3 = df2.copy()

In [106]: df3.index = new_index

选择并加入

In [107]: df1.loc[df3.index].join(df3)
Out[107]: 
                     Temp  SpCond   Sal  DO_pct  DO_mgl  Depth   pH  Turb   P04F   NH4F   N02F   N03F  NO23F  CHLA_N
2002-07-16 14:00:00  26.0   45.31  29.3    71.6     4.9   0.95  7.9    -5  0.053  0.073  0.005  0.021  0.026     8.6
2002-07-16 16:00:00  25.9   45.23  29.2    67.0     4.6   1.11  7.8    -6  0.029  0.069  0.002  0.016  0.018     9.6
2002-07-16 18:00:00  25.9   45.27  29.3    74.3     5.1   1.15  7.9    -6  0.023  0.073  0.000    NaN  0.014     5.8