EHB*_*EHB 4 nan series pandas fillna
如果连续 NAN 少于 3 个,我想填充 pandas 系列中的缺失值。
具有缺失值的原始系列:
s=pd.Series(pd.np.random.randn(20))
s[[1,3,5,7,12,13,14,15, 18]]=pd.np.nan
Run Code Online (Sandbox Code Playgroud)
给出:
0 0.444025
1 NaN
2 0.631753
3 NaN
4 -0.577121
5 NaN
6 1.299953
7 NaN
8 -0.252173
9 0.287641
10 0.941953
11 -1.624728
12 NaN
13 NaN
14 NaN
15 NaN
16 0.998952
17 0.195698
18 NaN
19 -0.788995
Run Code Online (Sandbox Code Playgroud)
但是,使用带有限制的 pandas.fillna() 只会填充指定的值数量(而不是预期的 CONSECUTIVE NAN 数量):
s.fillna(value=0, limit=3) #Fails to fill values at position 7 and forward
Run Code Online (Sandbox Code Playgroud)
所需的输出将在位置 1、3、5、7 和 18 处用 0 填充 NAN。它将在位置 12-15 处留下一系列 4 个 NaN。
SO 上的文档和其他帖子尚未解决此问题(例如此处)。文档似乎暗示此限制适用于连续的 NAN,而不是将填充的整个数据集中的整体数量。谢谢!
我们首先nan通过 查找值的位置pd.Series.notna。
当我们使用 时cumsum,每当遇到非空值时,我们都会增加累积和,从而为连续nan值生成方便的组。
然而,对于除了第一组(也许是第一组)之外的所有组,我们都以非空值开始。mask因此,我对每组内的空值总数进行求反并求和。
现在我fillna用它来掩盖值总和太多的pd.DataFrame.where地方。nan
mask = s.notna()
c_na = (~mask).groupby(mask.cumsum()).transform('sum')
filled = s.fillna(0).where(c_na.le(3))
s.fillna(filled)
0 1.418895
1 0.000000
2 -0.553732
3 0.000000
4 -0.101532
5 0.000000
6 -1.334803
7 0.000000
8 1.159115
9 0.309093
10 -0.047970
11 0.051567
12 NaN
13 NaN
14 NaN
15 NaN
16 0.623673
17 -0.786857
18 0.000000
19 0.310688
dtype: float64
Run Code Online (Sandbox Code Playgroud)
这是一种使用 Numpy/Pandas 的奇特np.bincount方式pd.factorize
v = s.values
m = np.isnan(v)
f, u = pd.factorize((~m).cumsum())
filled = np.where(
~m, v,
np.where(np.bincount(f, weights=mask)[f] <= 3, 0, np.nan)
)
pd.Series(filled, s.index)
0 1.418895
1 0.000000
2 -0.553732
3 0.000000
4 -0.101532
5 0.000000
6 -1.334803
7 0.000000
8 1.159115
9 0.309093
10 -0.047970
11 0.051567
12 NaN
13 NaN
14 NaN
15 NaN
16 0.623673
17 -0.786857
18 0.000000
19 0.310688
dtype: float64
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2177 次 |
| 最近记录: |