使用Pandas实现DataFrame中NaN值的循环填充问题
解决方案
原始数据
| A | B | |
|---|---|---|
| 0 | Abel | 10 |
| 1 | Ada | 8 |
| 2 | Beed | 15 |
| 3 | Calvin | 13 |
| 4 | NaN | 6 |
| 5 | NaN | 17 |
| 6 | NaN | 35 |
| 7 | NaN | 12 |
| 8 | NaN | 20 |
| 9 | NaN | 19 |
需求:用A列索引0-3的非NaN值循环填充后续的NaN,期望输出如下:
期望输出
| A | B | |
|---|---|---|
| 0 | Abel | 10 |
| 1 | Ada | 8 |
| 2 | Beed | 15 |
| 3 | Calvin | 13 |
| 4 | Abel | 6 |
| 5 | Ada | 17 |
| 6 | Beed | 35 |
| 7 | Calvin | 12 |
| 8 | Abel | 20 |
| 9 | Ada | 19 |
问题分析
原代码存在两个关键问题:
- 未导入
numpy库,np.nan会直接报错,无法生成正确的缺失值; - 使用
fillna结合Series填充时,虽逻辑可行但易受索引匹配影响,不如直接生成完整循环序列替换列更可靠。
正确代码
方法一:列表推导式生成循环序列
import pandas as pd import numpy as np data = {'A': ['Abel', 'Ada', 'Beed', 'Calvin', np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], 'B': [10, 8, 15, 13, 6, 17, 35, 12, 20, 19]} df = pd.DataFrame(data) # 获取用于循环填充的非NaN值列表 fill_list = df['A'].dropna().tolist() cycle_len = len(fill_list) # 生成与DataFrame长度一致的循环序列并替换原列 df['A'] = [fill_list[i % cycle_len] for i in range(len(df))] print(df)
方法二:使用numpy.tile快速生成循环序列
import pandas as pd import numpy as np data = {'A': ['Abel', 'Ada', 'Beed', 'Calvin', np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], 'B': [10, 8, 15, 13, 6, 17, 35, 12, 20, 19]} df = pd.DataFrame(data) fill_array = df['A'].dropna().to_numpy() # 生成重复足够次数的序列,截取前len(df)个元素替换原列 df['A'] = np.tile(fill_array, len(df) // len(fill_array) + 1)[:len(df)] print(df)
两种方法均能直接生成符合要求的循环填充序列,确保从第一个非NaN值开始循环填充后续缺失位。
内容的提问来源于stack exchange,提问作者Ruth Aju
相关产品推荐
相关产品推荐

