python - 使用 pandas.interpolate()

标签 python pandas dataframe interpolation

假设

test = pd.DataFrame([1,2,3,np.nan,np.nan,np.nan,np.nan,np.nan,4,5,6,np.nan,np.nan,np.nan,np.nan,np.nan,3,4,np.nan])

我想应用以下命令:

test.interpolate(limit = 2, limit_direction  = 'both', limit_area = 'inside')

返回

           0
0   1.000000
1   2.000000
2   3.000000
3   3.166667
4   3.333333
5        NaN
6   3.666667
7   3.833333
8   4.000000
9   5.000000
10  6.000000
11  5.500000
12  5.000000
13       NaN
14  4.000000
15  3.500000
16  3.000000
17  4.000000
18       NaN

问题:如何在一组 NaN 之前和之后应用对有效数字(即非 NaN)的最小数量的限制,以便应用插值

在此示例中,我想填充第一组 NaN,因为之前和之后至少有 3 个有效数字,但不插入第二组 NaN,因为 NaN 之后只有两个有效数字(而不是 3如我所愿)

预期结果:

           0
0   1.000000
1   2.000000
2   3.000000
3   3.166667
4   3.333333
5        NaN
6   3.666667
7   3.833333
8   4.000000
9   5.000000
10  6.000000
11       NaN
12       NaN
13       NaN
14       NaN
15       NaN
16  3.000000
17  4.000000
18       NaN

最佳答案

编辑 1:修改了我的第一个答案。另一种是基于 this Q&A 的某种掩码方法。 . 编辑 2:使用 deepcopy 将副本添加回 pd df 以避免按引用复制问题。

    import numpy as np
    import pandas as pd
    from copy import deepcopy

    a = np.array([1,2,3,np.nan,np.nan,np.nan,np.nan,np.nan,4,5,6,np.nan,np.nan,np.nan,np.nan,np.nan,3,4,np.nan,1])

    df = pd.DataFrame(a)
    # store values for later, to keep information from blocks that are below size limit:
    temp = deepcopy(df[df[0].notnull()]) 

    mask = np.concatenate(([False],np.isfinite(a),[False]))
    idx = np.nonzero(mask[1:] != mask[:-1])[0] # start and stop indices of your blocks of finite numbers
    counts = (np.flatnonzero(mask[1:] < mask[:-1]) - np.flatnonzero(mask[1:] > mask[:-1])) # n finite numbers per block

    sz_limit = 2 # set limit, exclusive in this case
    for i, size in enumerate(counts):
        if size <= sz_limit:
            a[idx[i*2]:idx[i*2+1]] = np.nan

现在调用插值并从“太小”的 block 中写回值:


    a_inter = pd.DataFrame(a).interpolate(limit = 2, limit_direction = 'both', limit_area = 'inside') 
    a_inter.update(other = temp)  

a_inter 就是

           0
0   1.000000
1   2.000000
2   3.000000
3   3.166667
4   3.333333
5        NaN
6   3.666667
7   3.833333
8   4.000000
9   5.000000
10  6.000000
11       NaN
12       NaN
13       NaN
14       NaN
15       NaN
16       NaN
17       NaN
18       NaN

要改进这个 hack,您可以将屏蔽放在一个函数中并摆脱 for 循环。

关于python - 使用 pandas.interpolate(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57143033/

相关文章:

python - 线程中的for循环在Python 3中运行一次

python - 使用多处理时无法重现 scikit-learn 和 numpy 相关代码

python - 如何按列分组并将一组的所有值复制到 Pandas 中的一行?

python - Pandas:编辑数据框的一部分,使其影响主数据框

r - 将数据框的名称提取为 R tidyverse 中的字符串

python - 如何获得两个数据帧的条件值之和之间的差异?

python - 写入文件的精确位置

python - 如何获得分割操作的结果?

python - 将 pandas 数据框中的值组合为字符串

python-3.x - Bokeh Legend 对象 - 将指定的颜色传递给图例