在DataFrame列的最后有效索引处插入指定序列的优雅实现
优化DataFrame序列插入实现方案
问题背景
给定一个包含空值(null)与数值的DataFrame,其中数值序列始终连续排列,不会被空值穿插,示例如下:
import pandas as pd import numpy as np df1 = pd.DataFrame({ 'A': [1, 2, 3, np.nan, np.nan], 'B': [np.nan, np.nan, 1, 2, 3], 'C': [np.nan, 1, 2, 3, np.nan] })
输出结果:
A B C 0 1.0 NaN NaN 1 2.0 NaN 1.0 2 3.0 1.0 2.0 3 NaN 2.0 3.0 4 NaN 3.0 NaN
需求说明
需创建一个与原DataFrame索引、列完全一致的新DataFrame,将指定序列插入其中,使序列结束于原DataFrame各列的最后非空值索引处。指定序列的长度与各列非空值长度不同,示例如下:
new_data = ['A','B']
期望输出:
A B C 0 NaN NaN NaN 1 A NaN NaN 2 B NaN A 3 NaN A B 4 NaN B NaN
当前实现方法
目前通过创建空DataFrame,遍历各列定义索引范围并赋值的方式实现,代码如下:
new_data = ['A','B'] df2 = pd.DataFrame(columns = df1.columns, index = df1.index) for col in df2: end = df1[col].last_valid_index()+1 start = end - len(new_data) df2[col][start:end] = new_data
该方法可实现需求,但代码较为繁琐,需寻求更优雅的解决方案。
优化方案
可以利用pandas.DataFrame.apply方法,将列级逻辑封装为函数,避免显式循环,代码更简洁紧凑:
import pandas as pd import numpy as np df1 = pd.DataFrame({ 'A': [1, 2, 3, np.nan, np.nan], 'B': [np.nan, np.nan, 1, 2, 3], 'C': [np.nan, 1, 2, 3, np.nan] }) new_data = ['A','B'] data_length = len(new_data) def fill_target_sequence(col): # 获取当前列最后非空值的下一个索引作为序列结束位置 end_idx = col.last_valid_index() + 1 # 计算序列起始位置 start_idx = end_idx - data_length # 创建与原列索引一致的空Series result_series = pd.Series(np.nan, index=col.index) # 确保起始位置合法(避免出现负索引) if start_idx >= 0: result_series.loc[start_idx:end_idx-1] = new_data return result_series # 应用函数到每一列,生成目标DataFrame df2 = df1.apply(fill_target_sequence)
方案说明
- 利用
apply遍历原DataFrame的每一列,将列级处理逻辑封装在fill_target_sequence函数中 - 函数内自动计算每列的序列插入起始/结束位置,构造对应空Series后赋值
- 代码结构更清晰,可读性更强,避免了手动逐列操作的繁琐步骤
内容的提问来源于stack exchange,提问作者r0bt
相关产品推荐
相关产品推荐

