Python 如何使用pandas仅在值之间插值(在列中最后一个NaN之前和之后停止)?

Python 如何使用pandas仅在值之间插值(在列中最后一个NaN之前和之后停止)?,python,pandas,interpolation,Python,Pandas,Interpolation,如果我有一个类似于此的df: print(df) A B C D E DATE_TIME 2016-08-10 13:57:00 3.6 A 1 NaN NaN 2016-08-10 13:58:00 4.7 A 1 4.5 NaN 2016-08-10 13:59:00 3.4 A 0 NaN 5.7 2016-08-10 14:00:00

如果我有一个类似于此的
df

print(df)
                       A  B  C    D    E
 DATE_TIME                               
2016-08-10 13:57:00  3.6  A  1  NaN  NaN
2016-08-10 13:58:00  4.7  A  1  4.5  NaN
2016-08-10 13:59:00  3.4  A  0  NaN  5.7
2016-08-10 14:00:00  3.5  A  0  NaN  NaN
2016-08-10 14:01:00  2.6  A  0  4.6  NaN
2016-08-10 14:02:00  4.8  A  0  NaN  4.3
2016-08-10 14:03:00  5.7  A  1  NaN  NaN
2016-08-10 14:04:00  5.5  A  1  5.7  NaN
2016-08-10 14:05:00  5.6  A  1  NaN  NaN
2016-08-10 14:06:00  7.8  A  1  NaN  5.2
2016-08-10 14:07:00  8.9  A  0  NaN  NaN
2016-08-10 14:08:00  3.6  A  0  NaN  NaN

print (df.dtypes)
A    float64
B     object
C      int64
D    float64
E    float64
dtype: object
多亏了社区的大量投入,我现在有了这段代码,它允许我将df的采样提高到秒间隔,对不同的
d类型应用不同的方法

int_cols = df.select_dtypes(['int64']).columns
index = pd.date_range(df.index[0], df.index[-1], freq="s")
df2 = df.reindex(index)

for col in df2:
if col == int_cols.all(): 
    df2[col].ffill(inplace=True)
    df2[col] = df2[col].astype(int)
elif df2[col].dtype == float:
    df2[col].interpolate(inplace=True)
else:
    df2[col].ffill(inplace=True)
我现在正在寻找一种方法,只在我的实际测量值之间进行插值。插值函数将我的上一次测量延长到
df
结束:

 df2.tail()
Out[75]: 
                            A  B  C    D    E
2016-08-10 14:07:56  3.953333  A  0  5.7  5.2
2016-08-10 14:07:57  3.865000  A  0  5.7  5.2
2016-08-10 14:07:58  3.776667  A  0  5.7  5.2
2016-08-10 14:07:59  3.688333  A  0  5.7  5.2
2016-08-10 14:08:00  3.600000  A  0  5.7  5.2
但我想在最后一次测量发生时停止此操作(例如在14:04:00
col['D']
和14:06:00
col['D']
),并离开NAN

它尝试将“limit”和“limit\u direction”的零值添加到“both”:

 for col in df2:
if col == int_cols.all(): 
    df2[col].ffill(inplace=True)
    df2[col] = df2[col].astype(int)
elif df2[col].dtype == float:
    df2[col].interpolate(inplace=True,limit=0, limit_direction='both')
else:
    df2[col].ffill(inplace=True)
但这并没有改变任何输出。然后,我尝试将我发现的解决方案纳入我的代码中:

for col in df2:
if col == int_cols.all(): 
    df2[col].ffill(inplace=True)
    df2[col] = df2[col].astype(int)
elif df2[col].dtype == float:
   df2[col].loc[df2[col].first_valid_index(): df2[col].last_valid_index()]=df2[col].loc[df2[col].first_valid_index(): df2[col].last_valid_index()].astype(float).interpolate(inplace=True)
else:
    df2[col].ffill(inplace=True)

…但这不起作用,我的
float 64
列现在完全是NaN…而且,我尝试插入代码的方式,我知道这只会影响
float
列。在理想的解决方案中,我希望将此
first\u valid\u index():。last\u valid\u index()
选择也设置到
对象
int64
列。谁能帮帮我吗。。谢谢

您可以回填空值,然后使用布尔索引获取每列的空值(必须是尾部空值)


你非常接近!下面是一个例子,它与您在文章末尾发布的代码非常相似:

import numpy as np
import pandas as pd

df = pd.DataFrame({'A': [np.nan, 1.0, np.nan, np.nan, 4.0, np.nan, np.nan],
                   'B': [np.nan, np.nan, 0.0, np.nan, np.nan, 2.0, np.nan]},
                  columns=['A', 'B'], 
                  index=pd.date_range(start='2016-08-10 13:50:00', periods=7, freq='S'))
print df

A_first = df['A'].first_valid_index()
A_last = df['A'].last_valid_index()
df.loc[A_first:A_last, 'A'] = df.loc[A_first:A_last, 'A'].interpolate()

B_first = df['B'].first_valid_index()
B_last = df['B'].last_valid_index()
df.loc[B_first:B_last, 'B'] = df.loc[B_first:B_last, 'B'].interpolate()

print df
结果:

                       A    B
2016-08-10 13:50:00  NaN  NaN
2016-08-10 13:50:01  1.0  NaN
2016-08-10 13:50:02  NaN  0.0
2016-08-10 13:50:03  NaN  NaN
2016-08-10 13:50:04  4.0  NaN
2016-08-10 13:50:05  NaN  2.0
2016-08-10 13:50:06  NaN  NaN

                       A         B
2016-08-10 13:50:00  NaN       NaN
2016-08-10 13:50:01  1.0       NaN
2016-08-10 13:50:02  2.0  0.000000
2016-08-10 13:50:03  3.0  0.666667
2016-08-10 13:50:04  4.0  1.333333
2016-08-10 13:50:05  NaN  2.000000
2016-08-10 13:50:06  NaN       NaN
代码中的两个问题是:

  • 如果要执行
    df[…]=df[…].interpolate()
    ,则需要 删除
    inplace=True
    ,因为这将使它返回
    None
    。这是您的主要问题,也是为什么您会收到所有
    nan
  • 虽然链式索引在这里似乎有效,但一般来说,链式索引是不好的:
  • 你想要:

    df.loc[A_first:A_last, 'A'] = df.loc[A_first:A_last, 'A'].interpolate()
    
    不是:


    有关更多详细信息,请参见此处:

    对于熊猫
    0.23.0
    可以在以下位置使用参数:


    非常感谢您的解释和有用的链接。我尝试了以下行
    df.loc[df['A'].first\u valid\u index():df['A'].last\u valid\u index()]=df.loc[df['A'].first\u valid\u index():df['A'].last\u valid\u index()]。用
    df
    插入(),看看它会做什么,我很惊讶B列也发生了变化。为什么会这样?我还更改了代码中的行:
    df2.loc[df2[col]。first\u valid\u index():df2[col]。last\u valid\u index()]=df2.loc[df[col]。first\u valid\u index():df2[col]。last\u valid\u index()。interpolate()
    ,这仍然不起作用。很抱歉再次询问,我真的想知道nit也在更改列B,因为您没有指定列,所以它会对每一列进行插值。一般来说,您需要的是
    df.loc[,]=df.loc[,]
    。具体来说,您需要的是
    df.loc[df['A'].first\u valid\u index():df['A'].last\u valid\u index(‌​), 'A']=df.loc[df['A'].第一个有效索引():df['A'].最后一个有效索引(‌​), 'A'].interpolate()
    df2.loc[df2[col]。第一个有效索引():df2[col]。最后一个有效索引‌​ex(),col]=df2.loc[df[col]。第一个有效索引():df2[col]。最后一个有效索引‌​x(),col].interpolate()
    谢谢!它现在开始工作了!但是我很困惑,当我运行这一行时(我修改了原始答案中的那一行)
    df.loc[df['A'].first\u valid\u index():df['A'].last\u valid\u index(),'A']=df.loc[df['A']。first\u valid\u index():df['A']。last\u valid\u index(),'A']
    它可以工作,但使用的这一行似乎完全相同
    df.loc[df['A'].first\u valid\u index():df['A'].last\u valid\u index(‌​‌​), 'A']=df.loc[df['A'].第一个有效索引():df['A'].最后一个有效索引(‌​‌​), 'A'].interpolate()
    作为上次编辑的副本,我得到
    语法错误:标识符中的字符无效。
    我疯了吗?奇怪,可能是在复制和粘贴过程中出现了一些看不见的字符?的确……我复制到记事本中,它是
    最后一个有效的索引(??)
    最后一个有效的索引(??)
    …非常感谢!谢谢!我仍在努力了解如何使用它!我知道它应该做什么,但我想我还不太清楚。。
    df.loc[A_first:A_last, 'A'] = df.loc[A_first:A_last, 'A'].interpolate()
    
    df['A'].loc[A_first:A_last] = df['A'].loc[A_first:A_last].interpolate()
    
    df = pd.DataFrame({'A': [np.nan, 1.0, np.nan, np.nan, 4.0, np.nan, np.nan],
                       'B': [np.nan, np.nan, 0.0, np.nan, np.nan, 2.0, np.nan]},
                      columns=['A', 'B'], 
                      index=pd.date_range(start='2016-08-10 13:50:00', periods=7, freq='S'))
    print (df)
                           A    B
    2016-08-10 13:50:00  NaN  NaN
    2016-08-10 13:50:01  1.0  NaN
    2016-08-10 13:50:02  NaN  0.0
    2016-08-10 13:50:03  NaN  NaN
    2016-08-10 13:50:04  4.0  NaN
    2016-08-10 13:50:05  NaN  2.0
    2016-08-10 13:50:06  NaN  NaN
    
    df = df.interpolate(limit_direction='both', limit_area='inside')
    print (df)
                           A         B
    2016-08-10 13:50:00  NaN       NaN
    2016-08-10 13:50:01  1.0       NaN
    2016-08-10 13:50:02  2.0  0.000000
    2016-08-10 13:50:03  3.0  0.666667
    2016-08-10 13:50:04  4.0  1.333333
    2016-08-10 13:50:05  NaN  2.000000
    2016-08-10 13:50:06  NaN       NaN