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

如何基于已有DataFrame的指定列非空值拆分生成新DataFrame?

实现方法:使用Pandas重塑与合并数据

当然有办法实现这个需求!下面我会给出两种可行的方案,分别适合小数据集和大数据集的场景:

方案一:直观循环法(适合小数据集)

这种方法逻辑清晰,容易理解,适合数据量不大的情况:

首先,我们先创建示例DataFrame(你可以直接替换成自己的数据集):

import pandas as pd
import numpy as np

# 构造示例数据
data = {
    'timestamp': ['2022-05-09 11:28:00', '2022-05-09 11:28:01', '2022-05-09 11:28:02', '2022-05-09 11:28:03'],
    'ID': [3.0, 3.0, 5.0, 5.0],
    'val1': [-11, -7, -8, -7],
    'sum': [100, 0.5, 50, np.nan],
    '3.0': [np.nan, np.nan, -35, 30],
    '5.0': [np.nan, np.nan, np.nan, np.nan],
    '7.0': [-45, -9, -20, np.nan],
    '9.0': [-67, np.nan, np.nan, np.nan],
    'sum_3.0': [80, 70, 12, 67],
    'sum_5.0': [123, 45, 23, 87],
    'sum_7.0': [0.98, 0.23, 0.0, 0.90],
    'sum_9.0': [345, 23, 14, 13]
}
df = pd.DataFrame(data)

接下来分三步处理:

  1. 保留原行数据:提取需求中要求保留的基础列
# 提取原行的基础列
original_rows = df[['timestamp', 'ID', 'val1', 'sum']].copy()
  1. 生成新增行数据:遍历每一行,检查目标列的非NaN值,生成对应新行
# 定义需要处理的列对:(值列, sum对应列)
column_pairs = [('3.0', 'sum_3.0'), ('5.0', 'sum_5.0'), ('7.0', 'sum_7.0'), ('9.0', 'sum_9.0')]
new_rows = []

for idx, row in df.iterrows():
    current_timestamp = row['timestamp']
    # 遍历每个列对,检查是否有非NaN值
    for val_col, sum_col in column_pairs:
        val = row[val_col]
        sum_val = row[sum_col]
        if not pd.isna(val):
            # 符合条件则添加新行
            new_rows.append({
                'timestamp': current_timestamp,
                'ID': float(val_col),  # 将列名转为数字ID
                'val1': val,
                'sum': sum_val
            })

# 把新行转为DataFrame
new_rows_df = pd.DataFrame(new_rows)
  1. 合并数据得到最终结果
# 合并原行和新行,重置索引
final_df = pd.concat([original_rows, new_rows_df], ignore_index=True)

方案二:向量化重塑法(适合大数据集)

如果你的数据集很大,循环会比较慢,推荐使用Pandas的melt函数进行向量化操作,效率更高:

# 步骤1:提取原行数据(和方案一相同)
original_rows = df[['timestamp', 'ID', 'val1', 'sum']].copy()

# 步骤2:将值列转为长格式
melted_vals = df.melt(
    id_vars=['timestamp'],
    value_vars=['3.0', '5.0', '7.0', '9.0'],
    var_name='ID',
    value_name='val1'
)

# 步骤3:将sum列转为长格式,并匹配对应ID
melted_sums = df.melt(
    id_vars=['timestamp'],
    value_vars=['sum_3.0', 'sum_5.0', 'sum_7.0', 'sum_9.0'],
    var_name='sum_col',
    value_name='sum'
)
# 去掉sum_前缀,得到对应的ID
melted_sums['ID'] = melted_sums['sum_col'].str.replace('sum_', '')

# 步骤4:合并值和sum的长格式数据,过滤NaN值
expanded_df = pd.merge(melted_vals, melted_sums, on=['timestamp', 'ID'], how='left')
expanded_df = expanded_df.dropna(subset=['val1']).drop(columns=['sum_col'])
# 将ID转为float类型
expanded_df['ID'] = expanded_df['ID'].astype(float)

# 步骤5:合并原行和展开后的行
final_df = pd.concat([original_rows, expanded_df], ignore_index=True)

运行以上任意一种方案,你都会得到和期望完全一致的DataFrame。

内容的提问来源于stack exchange,提问作者EngGu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:02:47