我希望在我的pandas数据框中向前填充一些值,但有限制。然而,该限制仅需要填充连续纳计数小于或等于极限的nans组。这是一个例子,
创建一个缺少数据的df,
import numpy as np
import pandas as pd
df = pd.DataFrame(
{'val': [1, 1, np.nan, np.nan, 2, 3, np.nan, np.nan, np.nan, np.nan, 1, 1]}
)
print(df)
val
0 1.0
1 1.0
2 NaN
3 NaN
4 2.0
5 3.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
11 1.0
现在,如果我们填充它,最多可以向前冲2步,
print(df.ffill(limit=2))
val
0 1.0
1 1.0
2 1.0
3 1.0
4 2.0
5 3.0
6 3.0 #
7 3.0 #
8 NaN
9 NaN
10 1.0
11 1.0
当我不希望它们使用#fill读取时(上图)。我想要的是获得以下内容,
print(df.ffill(limit=2, dont_fill_any_nan_gaps_bigger_than_limit=True))
val
0 1.0
1 1.0
2 1.0
3 1.0
4 2.0
5 3.0
6 NaN #
7 NaN #
8 NaN
9 NaN
10 1.0
11 1.0
当然,这不需要是ffill
中的单个参数,而是具有相同效果的参数。
答案 0 :(得分:2)
如果您在使用ffill
/ pd.Series.mask
/ pd.Series.where
后取消填充,则可以无条件np.where
。
v = df.value.isna() # df.value.isnull()
df = df.ffill(limit=2).mask(
v.groupby(v.ne(v.shift()).cumsum()).transform('size').gt(2)
)
value
0 1.0
1 1.0
2 1.0
3 1.0
4 2.0
5 3.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
11 1.0
答案 1 :(得分:2)
创建掩码,按groupby
和transform
NaN
过滤2
个size
以及ffill
~
的所有行,并应用a = df['value'].isna()
a = a.ne(a.shift()).cumsum()
m = (a.groupby(a).transform('size') > 2)
df[~m] = df[~m].ffill(limit=2)
print (df)
value
0 1.0
1 1.0
2 1.0
3 1.0
4 2.0
5 3.0
6 NaN
7 NaN
8 NaN
9 NaN
10 1.0
11 1.0
仅适用于WMIC
的反转条件的已过滤行:
@Echo Off
Set "VN="
For /F "EOL=V Tokens=*" %%A In (
'WMIC OS Where "Version<'4'" Get Version 2^>Nul'
) Do For /F "Tokens=3 Delims=." %%B In ("%%A") Do Set "VN=%%B"
If Not Defined VN Exit /B
If %VN% GEq 11082 If %VN% LEq 16299 Set "VN="
If Defined VN Exit /B
Rem your install code goes here.
答案 2 :(得分:2)
我从灵感来自jezral到我之前的answer的question获得了灵感,并将其应用于整个DataFrame。
我这样做是为了让我可以一次性处理整个DataFrame,这样每列都会ffill
各自列中的缺失值(使用我的额外约束)。
设置DataFrame,
df = pd.DataFrame(
{'val1': [1, 1, np.nan, np.nan, 2, 3, np.nan, np.nan, np.nan, np.nan, 1, 1],
'val2': [1, 2, np.nan, np.nan, 2, 4, 4, np.nan, np.nan, np.nan, np.nan, 2]}
)
print(df)
val1 val2
0 1.0 1.0
1 1.0 2.0
2 NaN NaN
3 NaN NaN
4 2.0 2.0
5 3.0 4.0
6 NaN # 4.0
7 NaN # NaN #
8 NaN # NaN #
9 NaN # NaN #
10 1.0 NaN #
11 1.0 2.0
现在执行mask
和ffill
,
mask_df = (
df.isnull()
.groupby([df.notnull().all(axis=1).cumsum()])
.rank(method='max') - 1
).gt(2)
df = df.ffill().mask(mask_df)
print(df)
val1 val2
0 1.0 1.0
1 1.0 2.0
2 1.0 2.0
3 1.0 2.0
4 2.0 2.0
5 3.0 4.0
6 NaN # 4.0
7 NaN # NaN #
8 NaN # NaN #
9 NaN # NaN #
10 1.0 NaN #
11 1.0 2.0
<强>释强>
我们groupby
使用非nan
值的累积总和。这意味着nan
值组合在一起。如果我们取这些rank
的最大值,我们得到nan
序列+ 1的长度。现在我们只使用mask
函数,如cᴏʟᴅsᴘᴇᴇᴅanswer所示。