如何在DataFrame中实现相同整数区间的条件向前填充?
问题:在DataFrame列的指定整数区间内向前填充NaN
先把你的原始数据和期望结果整理清楚:
原始数据
0 NaN 1 2.0 2 NaN 3 NaN 4 2.0 5 NaN 6 NaN 7 3.0 8 NaN 9 NaN 10 NaN 11 3.0 12 NaN 13 NaN 14 4.0 15 NaN 16 4.0
期望结果
0 NaN 1 2.0 2 2.0 3 2.0 4 2.0 5 NaN 6 NaN 7 3.0 8 3.0 9 3.0 10 3.0 11 3.0 12 NaN 13 NaN 14 4.0 15 4.0 16 4.0
解决方案
你提到想用enumerate和isinstance(x, int)的思路来实现,这个方向完全可行,我先给你实现这个手动遍历的版本,再补充一个更高效的Pandas原生方法,供你选择。
方法一:手动遍历实现(符合你的初始思路)
我们可以先把列转成列表,遍历记录每个整数的首次和最后出现位置,然后对区间内的NaN进行填充:
import pandas as pd import numpy as np # 构造原始DataFrame data = {'col': [np.nan, 2.0, np.nan, np.nan, 2.0, np.nan, np.nan, 3.0, np.nan, np.nan, np.nan, 3.0, np.nan, np.nan, 4.0, np.nan, 4.0]} df = pd.DataFrame(data) # 转成列表方便遍历 col_values = df['col'].tolist() # 存储每个整数的起始和结束索引 value_ranges = {} # 第一步:遍历记录每个整数的首尾位置 for idx, val in enumerate(col_values): if not pd.isna(val): # 把数值转成整数(因为你的数据是float类型的整数) int_val = int(val) if int_val not in value_ranges: value_ranges[int_val] = {'start': idx, 'end': idx} else: # 更新最后出现的索引 value_ranges[int_val]['end'] = idx # 第二步:填充每个区间内的NaN for val, ranges in value_ranges.items(): start_idx = ranges['start'] end_idx = ranges['end'] for i in range(start_idx, end_idx + 1): if pd.isna(col_values[i]): col_values[i] = val # 把填充后的数据放回DataFrame df['filled_col'] = col_values print(df['filled_col'])
这个方法完全按照你想的enumerate思路来,逻辑清晰,适合理解填充过程。
方法二:Pandas原生高效实现
如果追求代码简洁和运行效率,推荐用Pandas的分组和填充组合操作,比手动遍历快很多,尤其是数据量大的时候:
import pandas as pd import numpy as np # 构造原始DataFrame data = {'col': [np.nan, 2.0, np.nan, np.nan, 2.0, np.nan, np.nan, 3.0, np.nan, np.nan, np.nan, 3.0, np.nan, np.nan, 4.0, np.nan, 4.0]} df = pd.DataFrame(data) # 创建分组标记:只保留每个整数最后出现位置对应的分组,其他位置暂时标记为NaN df['group'] = df['col'].ffill().where(df['col'].notna().cumsum().duplicated(keep='last'), np.nan) # 对每个分组内的NaN进行向前填充 df['filled_col'] = df.groupby('group')['col'].ffill() # 删掉临时的分组列 df = df.drop('group', axis=1) print(df['filled_col'])
这个方法的核心是先给每个需要填充的区间打上分组标签,然后用groupby结合ffill(向前填充),精准地只填充每个整数首次出现到最后出现的区间,完全符合你的需求。
内容的提问来源于stack exchange,提问作者J Walker
相关产品推荐
相关产品推荐

