假设
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/