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

Python实现DataFrame行复制、ID列与type列生成方案

问题解决:DataFrame行复制与新增列生成

输入DataFrame

c1  c2  c3  c4  c5  c6  c7  c8    c9 c10 c11
56  1   2   4   1.0 1   4.0 1.0   2  2   18000.0
52  2   2   5   3.0 1   4.0 1.0   1  1   0.0
82  2   2   5   4.0 2   4.0 1.0   1  1   0.0
26  1   2   4   2.0 1   4.0 1.0   2  2   12000.0
65  1   2   4   1.0 1   4.0 23.0  2  1   324900.0

需求

  • 将输入DataFrame的每一行复制3次
  • 生成id列:对应原数据的行号(从1开始),每个行号重复3次
  • 生成type列:对每条原始记录按1、2、3循环取值

期望输出

id type  c1  c2  c3  c4  c5  c6  c7  c8   c9 c10 c11
1  1     56 1   2   4   1.0 1   4.0 1.0   2  2   18000.0
1  2     56 1   2   4   1.0 1   4.0 1.0   2  2   18000.0
1  3     56 1   2   4   1.0 1   4.0 1.0   2  2   18000.0
2  1     52 2   2   5   3.0 1   4.0 1.0   1  1   0.0
2  2     52 2   2   5   3.0 1   4.0 1.0   1  1   0.0
2  3     52 2   2   5   3.0 1   4.0 1.0   1  1   0.0
3  1     82 2   2   5   4.0 2   4.0 1.0   1  1   0.0
3  2     82 2   2   5   4.0 2   4.0 1.0   1  1   0.0
3  3     82 2   2   5   4.0 2   4.0 1.0   1  1   0.0
4  1     26 1   2   4   2.0 1   4.0 1.0   2  2   12000.0
4  2     26 1   2   4   2.0 1   4.0 1.0   2  2   12000.0
4  3     26 1   2   4   2.0 1   4.0 1.0   2  2   12000.0
5  1     65 1   2   4   1.0 1   4.0 23.0  2  1   324900.0
5  2     65 1   2   4   1.0 1   4.0 23.0  2  1   324900.0
5  3     65 1   2   4   1.0 1   4.0 23.0  2  1   324900.0

你的尝试代码(存在问题)

(df
     .dropna()
     .assign(id =  lambda x: range(1, len(x) + 1)
            )
      .pipe(lambda x: x.loc[x.index.repeat(3)])
      .assign(id = lambda x: np.r_[:len(x)] % 3 + 1,
              type = lambda x: np.r_[:len(x)] % 3 + 1))

问题分析:第二次assign覆盖了初始正确的id值,用np.r_[:len(x)] %3 +1生成的是1、2、3循环序列,而非原行号重复3次的结果。


正确实现方法

方法一:保留初始id,新增type列

先给原DataFrame添加从1开始的行号作为id,再重复行、生成type列:

import pandas as pd
import numpy as np

result = (df
          .dropna()
          .assign(id=lambda x: range(1, len(x)+1))  # 生成原行号id
          .loc[lambda x: x.index.repeat(3)]  # 每行重复3次
          .assign(type=lambda x: np.tile([1,2,3], len(x)//3))  # 循环生成type值
          .reset_index(drop=True))

方法二:重复后计算id

无需提前添加id,通过重复后的索引位置反推原行号:

result = (df
          .dropna()
          .loc[lambda x: x.index.repeat(3)]
          .assign(id=lambda x: (x.index // 3) + 1,  # 从重复后的索引计算原行号
                  type=lambda x: np.tile([1,2,3], len(df))))

方法三:用explode简化逻辑

给每行添加包含[1,2,3]的type列表,再展开列表生成多行:

result = (df
          .dropna()
          .assign(id=range(1, len(df)+1),
                  type=[[1,2,3]]*len(df))
          .explode('type')
          .reset_index(drop=True))

以上三种方法均可得到符合要求的输出,其中方法三逻辑更直观,代码更简洁。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:47:46