当 NaN 超过限制时如何限制 pandas 插值
How to limit pandas interpolation when there is more NaN than the limit
我想插入一个 pandas 数据框,但找不到解决我的问题的简单方法。
这是我的 pandas df:
df = pandas.DataFrame(numpy.array([numpy.nan, 1, 1, numpy.nan, \
numpy.nan, 1, numpy.nan, numpy.nan, numpy.nan, numpy.nan, 1]),columns=['a'])
a
0 NaN
1 1.0
2 1.0
3 NaN
4 NaN
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
我想要以下结果:
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
为此,我使用了插值函数,但它总是推断数据:
df2=df.interpolate(limit=2, limit_area='inside' ,method='linear')
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 NaN
9 NaN
10 1.0
是否可以仅在限制参数范围内存在非 NaN 值时进行插值? (即:第 6 行和第 7 行的值应为 NaN,因为第 8 行也是 NaN)。我的印象是 limit_area 仅用于 df 的结尾。
谢谢
要实现您想要的效果,首先创建一个系列,计算每组 NaN
的连续 NaN
值的数量,并将该值广播回组中的每一行。然后插入整个系列并使用 mask
到 NaN
不应该被插入的所有内容。
s = df['a'].notnull()
s = s.ne(s.shift()).cumsum()
m = df.groupby([s, df['a'].isnull()])['a'].transform('size').where(df['a'].isnull())
#0 1.0
#1 NaN
#2 NaN
#3 2.0
#4 2.0
#5 NaN
#6 4.0
#7 4.0
#8 4.0
#9 4.0
#10 NaN
df.interpolate(limit_area='inside', method='linear').mask(m>2)
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
我想插入一个 pandas 数据框,但找不到解决我的问题的简单方法。 这是我的 pandas df:
df = pandas.DataFrame(numpy.array([numpy.nan, 1, 1, numpy.nan, \
numpy.nan, 1, numpy.nan, numpy.nan, numpy.nan, numpy.nan, 1]),columns=['a'])
a
0 NaN
1 1.0
2 1.0
3 NaN
4 NaN
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
我想要以下结果:
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
为此,我使用了插值函数,但它总是推断数据:
df2=df.interpolate(limit=2, limit_area='inside' ,method='linear')
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 NaN
9 NaN
10 1.0
是否可以仅在限制参数范围内存在非 NaN 值时进行插值? (即:第 6 行和第 7 行的值应为 NaN,因为第 8 行也是 NaN)。我的印象是 limit_area 仅用于 df 的结尾。
谢谢
要实现您想要的效果,首先创建一个系列,计算每组 NaN
的连续 NaN
值的数量,并将该值广播回组中的每一行。然后插入整个系列并使用 mask
到 NaN
不应该被插入的所有内容。
s = df['a'].notnull()
s = s.ne(s.shift()).cumsum()
m = df.groupby([s, df['a'].isnull()])['a'].transform('size').where(df['a'].isnull())
#0 1.0
#1 NaN
#2 NaN
#3 2.0
#4 2.0
#5 NaN
#6 4.0
#7 4.0
#8 4.0
#9 4.0
#10 NaN
df.interpolate(limit_area='inside', method='linear').mask(m>2)
a
0 NaN
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0