如何提取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
相关产品推荐
相关产品推荐

