Pandas 数据帧中的插值函数

Interpolate function in Pandas Dataframe

在 Pandas 中用于插入 DataFrame 的方程式有哪些?

阅读以下内容link,我找不到与它们相关的内容。

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.interpolate.html

我正需要这个:

但我不确定 interpolate() 函数是否在做同样的事情。如果是这样,我是否可以将其更改为那样工作?

编辑:数据帧示例:

df = pd.DataFrame([[np.nan, 10, np.nan, 20, 17, np.nan, np.nan, 14, np.nan, 10, np.nan],
                  [5, np.nan, 0, np.nan, np.nan, np.nan, 5, np.nan, 10, np.nan, np.nan],
                  [3, np.nan, np.nan, np.nan, np.nan, np.nan, 2, np.nan, np.nan, np.nan, np.nan],
                  [np.nan, np.nan, np.nan, 3, 4, 5, np.nan, 7, 8, 9, np.nan]],
                  columns=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'])

不幸的是,interpolate 方法并没有做到这一点。不过还是可以达到你想要的效果。

简答

df.interpolate(limit=1).mul(~(df.shift(-1).isna() & df.isna())).fillna(0)

分步说明

默认情况下,插值方法将值视为等间距。例如,如果您输入 [0,NaN,10,NaN,NaN,16],您将得到 [0,5,10,12,14,16]。此行为由插值函数的 method 参数控制。您不必根据自己的情况更改它。

>>> df = pd.DataFrame([np.nan, 10, np.nan, 20, 17, np.nan, np.nan, 14, np.nan, 10, np.nan], columns=["value"])
>>> df
    value
0     NaN
1    10.0
2     NaN
3    20.0
4    17.0
5     NaN
6     NaN
7    14.0
8     NaN
9    10.0
10    NaN

>>> df.interpolate()
    value
0     NaN
1    10.0
2    15.0
3    20.0
4    17.0
5    16.0
6    15.0
7    14.0
8    12.0
9    10.0
10   10.0

现在,默认行为将替换任何 NaN,但您不希望替换连续的 NaN,因此您需要使用 limit 参数。

这个参数限制了将被替换的连续NaN的个数,但关键是,如果你将限制设置为1,连续NaN中的第一个NaN仍然会被替换;你不想要那个!

>>> df.interpolate(limit=1)
    value
0     NaN
1    10.0
2    15.0
3    20.0
4    17.0
5    16.0
6     NaN
7    14.0
8    12.0
9    10.0
10   10.0

要去除那些第一个值,您需要知道哪些值是 NaN 并且紧跟另一个 NaN。使用这个:

>>> df.shift(-1).isna() & df.isna()
        value 
0   False 
1   False 
2   False 
3   False 
4   False 
5    True 
6   False 
7   False 
8   False 
9   False 
10   True 

然后您可以将您的数据帧乘以该表达式的否定 (~)。 (注意 n*False = 0n*True = n)`

>>> df.interpolate(limit=1).mul(~(df.shift(-1).isna() & df.isna()))
    value
0     NaN
1    10.0
2    15.0
3    20.0
4    17.0
5     0.0
6     NaN
7    14.0
8    12.0
9    10.0
10    0.0

最后,使用 fillna

将剩余的 NaN 值替换为 0
>>> df.interpolate(limit=1).mul(~(df.shift(-1).isna() & df.isna())).fillna(0)
    value
0     0.0
1    10.0
2    15.0
3    20.0
4    17.0
5     0.0
6     0.0
7    14.0
8    12.0
9    10.0
10    0.0