缺失值 NaN 替换条件 Python
Missing values NaN replace conditional Python
我有一个数据集,其中包含一系列国家和年份的几个指标的值(3072,1134 行和列),但有些为 NaN。
在下面找到数据集的样本:
Year
Country
Submitted
Age12
Age14
...
2017
CHI
1
267
136
...
2018
CHI
1
267
NaN
...
2019
CHI
NaN
NaN
NaN
...
2020
CHI
1
244
203
...
2017
ALB
1
160
148
...
2018
ALB
1
163
165
...
2019
ALB
1
NaN
NaN
...
2020
ALB
1
161
NaN
...
2017
GER
1
NaN
320
...
2018
GER
1
451
381
...
2019
GER
NaN
NaN
NaN
...
2020
GER
1
361
321
2017
BRI
1
NaN
NaN
...
2018
BRI
1
NaN
NaN
...
2019
BRI
NaN
NaN
NaN
...
2020
BRI
1
322
298
我想根据 Submitted
列的值替换缺失值。
仅当相应的 Submitted
值为“NaN”时,我才想更改前一行的值。
这就是我想要的:
Year
Country
Submitted
Age12
Age14
...
2017
CHI
1
267
136
...
2018
CHI
1
267
NaN
...
2019
CHI
1
267
NaN
...
2020
CHI
1
244
203
...
2017
ALB
1
160
148
...
2018
ALB
1
163
165
...
2019
ALB
1
NaN
NaN
...
2020
ALB
1
161
NaN
...
2017
GER
1
NaN
320
...
2018
GER
1
451
381
...
2019
GER
1
451
381
...
2020
GER
1
361
321
...
2017
BRI
1
NaN
NaN
...
2018
BRI
1
NaN
NaN
...
2019
BRI
1
NaN
NaN
...
2020
BRI
1
322
298
在社区的帮助下,我尝试使用
df = df.where(~df.Sumbitted.isnull(), df.fillna(axis=0, method='ffill'))
和
df = df.where(~df.Sumbitted.isnull(), df.fillna(axis=0, method='ffill',limit=2))
和
df = df.where(~df.Sumbitted.isnull(), interpolate(method="pad", limit=2))
但是,使用这些选项我得到以下结果。问题是代码检索了先前的非 NaN 值,但在先前值是 NaN 的情况下,代码检索先前值之前的值,直到找到非 NaN 值。
输出:
Year
Country
Submitted
Age12
Age14
...
2017
CHI
1
267
136
...
2018
CHI
1
267
NaN
...
2019
CHI
1
267
136
...
2020
CHI
1
244
203
...
2017
ALB
1
160
148
...
2018
ALB
1
163
165
...
2019
ALB
1
NaN
NaN
...
2020
ALB
1
161
NaN
...
2017
GER
1
NaN
320
...
2018
GER
1
451
381
...
2019
GER
1
451
381
...
2020
GER
1
361
321
2017
BRI
1
NaN
NaN
...
2018
BRI
1
NaN
NaN
...
2019
BRI
1
361
321
...
2020
BRI
1
322
298
查看 CHI 2019 Age14 和 BRI Age12 和 Age14 的错误输出
你知道如何通过修复这段代码来解决这个问题吗?
使用循环或选择这两列(Age14 和 Age12)的解决方案不是最优的,因为我有多个列(示例中的“...”)并且需要一个系统的解决方案。
谢谢
您可以使用参数 limit=1
来限制仅从前一行值开始填充,而不是进一步向上:
df = df.where(~df.Submitted.isnull(), df.fillna(axis=0, method='ffill',limit=1))
或者更好的是,简化您的代码,如下所示:
使用 .mask()
instead of .where
so that your code don't need extra step to negate the boolean mask. Also, use ffill()
这是 .fillna(axis=0, method='ffill')
的简化形式:
df = df.mask(df.Submitted.isna(), df.ffill(limit=1))
结果:
print(df)
Year Country Submitted Age12 Age14
0 2017 CHI 1.0 267.0 136.0
1 2018 CHI 1.0 267.0 NaN
2 2019 CHI 1.0 267.0 NaN
3 2020 CHI 1.0 244.0 203.0
4 2017 ALB 1.0 160.0 148.0
5 2018 ALB 1.0 163.0 165.0
6 2019 ALB 1.0 NaN NaN
7 2020 ALB 1.0 161.0 NaN
8 2017 GER 1.0 NaN 320.0
9 2018 GER 1.0 451.0 381.0
10 2019 GER 1.0 451.0 381.0
11 2020 GER 1.0 361.0 321.0
12 2017 BRI 1.0 NaN NaN
13 2018 BRI 1.0 NaN NaN
14 2019 BRI 1.0 NaN NaN
15 2020 BRI 1.0 322.0 298.0
我有一个数据集,其中包含一系列国家和年份的几个指标的值(3072,1134 行和列),但有些为 NaN。
在下面找到数据集的样本:
Year | Country | Submitted | Age12 | Age14 | ... |
---|---|---|---|---|---|
2017 | CHI | 1 | 267 | 136 | ... |
2018 | CHI | 1 | 267 | NaN | ... |
2019 | CHI | NaN | NaN | NaN | ... |
2020 | CHI | 1 | 244 | 203 | ... |
2017 | ALB | 1 | 160 | 148 | ... |
2018 | ALB | 1 | 163 | 165 | ... |
2019 | ALB | 1 | NaN | NaN | ... |
2020 | ALB | 1 | 161 | NaN | ... |
2017 | GER | 1 | NaN | 320 | ... |
2018 | GER | 1 | 451 | 381 | ... |
2019 | GER | NaN | NaN | NaN | ... |
2020 | GER | 1 | 361 | 321 | |
2017 | BRI | 1 | NaN | NaN | ... |
2018 | BRI | 1 | NaN | NaN | ... |
2019 | BRI | NaN | NaN | NaN | ... |
2020 | BRI | 1 | 322 | 298 |
我想根据 Submitted
列的值替换缺失值。
仅当相应的 Submitted
值为“NaN”时,我才想更改前一行的值。
这就是我想要的:
Year | Country | Submitted | Age12 | Age14 | ... |
---|---|---|---|---|---|
2017 | CHI | 1 | 267 | 136 | ... |
2018 | CHI | 1 | 267 | NaN | ... |
2019 | CHI | 1 | 267 | NaN | ... |
2020 | CHI | 1 | 244 | 203 | ... |
2017 | ALB | 1 | 160 | 148 | ... |
2018 | ALB | 1 | 163 | 165 | ... |
2019 | ALB | 1 | NaN | NaN | ... |
2020 | ALB | 1 | 161 | NaN | ... |
2017 | GER | 1 | NaN | 320 | ... |
2018 | GER | 1 | 451 | 381 | ... |
2019 | GER | 1 | 451 | 381 | ... |
2020 | GER | 1 | 361 | 321 | ... |
2017 | BRI | 1 | NaN | NaN | ... |
2018 | BRI | 1 | NaN | NaN | ... |
2019 | BRI | 1 | NaN | NaN | ... |
2020 | BRI | 1 | 322 | 298 |
在社区的帮助下,我尝试使用
df = df.where(~df.Sumbitted.isnull(), df.fillna(axis=0, method='ffill'))
和
df = df.where(~df.Sumbitted.isnull(), df.fillna(axis=0, method='ffill',limit=2))
和
df = df.where(~df.Sumbitted.isnull(), interpolate(method="pad", limit=2))
但是,使用这些选项我得到以下结果。问题是代码检索了先前的非 NaN 值,但在先前值是 NaN 的情况下,代码检索先前值之前的值,直到找到非 NaN 值。
输出:
Year | Country | Submitted | Age12 | Age14 | ... |
---|---|---|---|---|---|
2017 | CHI | 1 | 267 | 136 | ... |
2018 | CHI | 1 | 267 | NaN | ... |
2019 | CHI | 1 | 267 | 136 | ... |
2020 | CHI | 1 | 244 | 203 | ... |
2017 | ALB | 1 | 160 | 148 | ... |
2018 | ALB | 1 | 163 | 165 | ... |
2019 | ALB | 1 | NaN | NaN | ... |
2020 | ALB | 1 | 161 | NaN | ... |
2017 | GER | 1 | NaN | 320 | ... |
2018 | GER | 1 | 451 | 381 | ... |
2019 | GER | 1 | 451 | 381 | ... |
2020 | GER | 1 | 361 | 321 | |
2017 | BRI | 1 | NaN | NaN | ... |
2018 | BRI | 1 | NaN | NaN | ... |
2019 | BRI | 1 | 361 | 321 | ... |
2020 | BRI | 1 | 322 | 298 |
查看 CHI 2019 Age14 和 BRI Age12 和 Age14 的错误输出
你知道如何通过修复这段代码来解决这个问题吗? 使用循环或选择这两列(Age14 和 Age12)的解决方案不是最优的,因为我有多个列(示例中的“...”)并且需要一个系统的解决方案。
谢谢
您可以使用参数 limit=1
来限制仅从前一行值开始填充,而不是进一步向上:
df = df.where(~df.Submitted.isnull(), df.fillna(axis=0, method='ffill',limit=1))
或者更好的是,简化您的代码,如下所示:
使用 .mask()
instead of .where
so that your code don't need extra step to negate the boolean mask. Also, use ffill()
这是 .fillna(axis=0, method='ffill')
的简化形式:
df = df.mask(df.Submitted.isna(), df.ffill(limit=1))
结果:
print(df)
Year Country Submitted Age12 Age14
0 2017 CHI 1.0 267.0 136.0
1 2018 CHI 1.0 267.0 NaN
2 2019 CHI 1.0 267.0 NaN
3 2020 CHI 1.0 244.0 203.0
4 2017 ALB 1.0 160.0 148.0
5 2018 ALB 1.0 163.0 165.0
6 2019 ALB 1.0 NaN NaN
7 2020 ALB 1.0 161.0 NaN
8 2017 GER 1.0 NaN 320.0
9 2018 GER 1.0 451.0 381.0
10 2019 GER 1.0 451.0 381.0
11 2020 GER 1.0 361.0 321.0
12 2017 BRI 1.0 NaN NaN
13 2018 BRI 1.0 NaN NaN
14 2019 BRI 1.0 NaN NaN
15 2020 BRI 1.0 322.0 298.0