You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取DataFrame每行的第一个和第N个非空值

如何提取DataFrame每行的第一个和第N个非空值

嗨,我来帮你解决这个提取每行第N个非空值的问题!先回顾下你的输入和预期输出:

输入DataFrame:

0     1     2     3    4
date                                
2007-02-15  NaN -0.88  0.80   NaN  0.5
2007-02-16  0.5 -0.84   NaN  0.29  NaN
2007-02-19  NaN -0.84  0.79  0.29  NaN
2007-02-20  0.5  0.50  0.67  0.20  0.5

预期输出:

1st   3rd
date                
2007-02-15 -0.88  0.50
2007-02-16  0.50  0.29
2007-02-19 -0.84  0.29
2007-02-20  0.50  0.67

你已经知道怎么提取第一个非空值了,下面给你两种提取第N个非空值的方法,适配不同场景:


方法一:直观的apply函数法(适合小数据集)

这种方法逻辑清晰,容易理解,适合数据量不大的情况。我们可以定义一个通用函数,用来提取每行指定位置的非空值:

import pandas as pd

# 先构造你的输入DataFrame
data = {
    0: [None, 0.5, None, 0.5],
    1: [-0.88, -0.84, -0.84, 0.50],
    2: [0.80, None, 0.79, 0.67],
    3: [None, 0.29, 0.29, 0.20],
    4: [0.5, None, None, 0.5]
}
df = pd.DataFrame(data, index=pd.date_range('2007-02-15', periods=4, freq='B'))

def get_nth_non_null(row, n):
    # 取出该行所有非空值
    non_null_vals = row.dropna().values
    # 如果非空值数量足够,返回第n个(注意:这里n从0开始计数,第三个非空值对应n=2)
    # 非空值不足时返回None,避免报错
    return non_null_vals[n] if len(non_null_vals) > n else None

# 生成结果DataFrame
result_df = pd.DataFrame()
result_df['1st'] = df.apply(get_nth_non_null, n=0, axis=1)  # 第一个非空值
result_df['3rd'] = df.apply(get_nth_non_null, n=2, axis=1)  # 第三个非空值

运行后就能得到你想要的结果,这个方法可以灵活调整n的值,提取任意位置的非空值。


方法二:高效向量化法(适合大数据集)

如果你的DataFrame行数很多,apply的效率可能不够理想,这时候可以用stack+groupby的组合,借助pandas的向量化操作提升速度:

import pandas as pd

# 构造输入DataFrame(同方法一)
data = {
    0: [None, 0.5, None, 0.5],
    1: [-0.88, -0.84, -0.84, 0.50],
    2: [0.80, None, 0.79, 0.67],
    3: [None, 0.29, 0.29, 0.20],
    4: [0.5, None, None, 0.5]
}
df = pd.DataFrame(data, index=pd.date_range('2007-02-15', periods=4, freq='B'))

# 1. 堆叠每行的非空值,自动过滤NaN
stacked_data = df.stack().reset_index(level=1, drop=True).reset_index()
# 2. 对每个日期分组,给非空值编序号(从0开始)
stacked_data['non_null_rank'] = stacked_data.groupby('date').cumcount()
# 3. 筛选出第一个(rank=0)和第三个(rank=2)非空值
filtered = stacked_data[stacked_data['non_null_rank'].isin([0, 2])]
# 4. 转成宽格式,重命名列得到最终结果
result_df = filtered.pivot(index='date', columns='non_null_rank', values=0)
result_df.columns = ['1st', '3rd']

这种方法避开了逐行循环,用pandas内置的高效操作处理数据,在大数据集上的效率会比apply高很多。


备注:内容来源于stack exchange,提问作者younggotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 11:37:36