如何按非重叠两行拆分DataFrame生成训练集与验证集
按固定非重叠两行拆分含NA值的DataFrame为多组训练/验证集
需求说明
需要将包含NA值的DataFrame拆分为多组训练集与验证集,规则如下:
- 仅选取非NA的连续两行作为验证集(NA行始终保留在训练集)
- 每次选取的验证集与之前的非重叠
- 剩余所有行作为训练集,重复操作直到所有可分组的非NA行都被用作验证集
示例数据
x y ID 39.54 116.39 ID1 38.27 117.26 ID2 28.27 119.55 ID3 27.34 119.43 ID4 NA NA ID5 30.17 109.28 ID6 9.083333333 39.08333333 ID7 NA NA ID8 NA NA ID9 NA NA ID10
实现方案(基于Pandas)
步骤1:创建示例DataFrame
import pandas as pd import numpy as np # 构建示例数据 data = { 'x': [39.54, 38.27, 28.27, 27.34, np.nan, 30.17, 9.083333333, np.nan, np.nan, np.nan], 'y': [116.39, 117.26, 119.55, 119.43, np.nan, 109.28, 39.08333333, np.nan, np.nan, np.nan], 'ID': ['ID1', 'ID2', 'ID3', 'ID4', 'ID5', 'ID6', 'ID7', 'ID8', 'ID9', 'ID10'] } df = pd.DataFrame(data)
步骤2:拆分逻辑实现
# 筛选出x和y不同时为NA的行的索引(这些行可作为验证集候选) non_na_mask = ~(df['x'].isna() & df['y'].isna()) non_na_indices = df[non_na_mask].index # 将候选索引按每2个一组拆分 val_index_groups = [non_na_indices[i:i+2] for i in range(0, len(non_na_indices), 2)] # 生成所有训练集-验证集对 train_val_sets = [] for val_indices in val_index_groups: # 只保留刚好2行的验证集(避免最后一组不足2行的情况) if len(val_indices) == 2: # 提取验证集 val_df = df.loc[val_indices].copy() # 提取训练集:原DataFrame移除当前验证集的行 train_df = df.drop(val_indices).copy() train_val_sets.append((train_df, val_df))
步骤3:查看结果
# 遍历打印所有分组结果 for idx, (train, val) in enumerate(train_val_sets, 1): print(f"--- 第{idx}组 ---") print("训练集:") print(train.reset_index(drop=True)) # 重置索引让输出更整洁 print("\n验证集:") print(val.reset_index(drop=True)) print("\n" + "-"*60 + "\n")
运行后会得到和示例完全一致的分组结果:
- 第1组验证集为ID1、ID2,训练集包含剩余所有行
- 第2组验证集为ID3、ID4,训练集包含剩余所有行
- 第3组验证集为ID6、ID7,训练集包含剩余所有行
说明
- 如果你的NA判定规则不同(比如只要x或y有一个非NA就算候选),只需修改
non_na_mask的条件即可 - 若需要将所有行(包括NA行)都按每两行分组作为验证集,直接去掉NA筛选步骤,用
np.arange(len(df))生成索引分组即可
内容的提问来源于stack exchange,提问作者honeymoon
相关产品推荐
相关产品推荐

