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

如何在Pandas中无循环将DataFrame转换为索引无冲突的列结构?

解决方案:无循环实现DataFrame到索引无冲突列结构的转换

要实现这个需求,我们可以利用Pandas的向量化操作完成,核心思路是:识别每行非零值的分布模式,将每行非零值的和映射到对应模式的新列中,确保每行仅在一个新列有值(其余为0)。以下是具体步骤和代码实现:

步骤拆解

  1. 计算每行非零值的总和:目标结果中的非零值是原行所有非零值的和,用sum(axis=1)快速完成计算。
  2. 提取非零值的分布模式:对每行,获取所有非零值所在的列名组成的元组,作为该行列分布的唯一标识(比如('col1',)表示仅col1有非零值,('col1','col2')表示col1和col2有非零值)。
  3. 模式编码与新列命名:将唯一的分布模式映射为数字编码,再生成对应的新列名(如new_col1、new_col2)。
  4. 构造结果DataFrame:通过独热编码将模式编码转换为二进制矩阵,再与行总和相乘,自动填充对应列的值,其余列置0。

完整代码实现

import pandas as pd

# 构造原DataFrame
data = [
    [1,0,0,0],
    [2,0,0,0],
    [3,1,0,0],
    [4,2,1,0],
    [0,3,2,0],
    [0,4,3,0],
    [0,5,4,0],
    [0,0,5,1],
    [0,0,6,2],
    [0,0,0,3]
]
df = pd.DataFrame(data, columns=['col1','col2','col3','col4'])

# 1. 计算每行非零值的总和
row_sums = df.sum(axis=1)

# 2. 提取每行的非零列分布模式(元组形式)
non_zero_patterns = df.ne(0).apply(lambda row: tuple(row[row].index), axis=1)

# 3. 将模式转换为编码,并生成新列名
pattern_codes, _ = pd.factorize(non_zero_patterns)
new_columns = [f'new_col{i+1}' for i in range(pattern_codes.max() + 1)]

# 4. 无循环构造结果:独热编码 × 行总和
pattern_dummies = pd.get_dummies(pattern_codes, prefix='new_col')
pattern_dummies.columns = new_columns
result = pattern_dummies.multiply(row_sums, axis=0)

print(result)

代码细节解释

  • df.ne(0):生成布尔矩阵,标记每个位置是否为非零值。
  • apply(lambda row: tuple(row[row].index), axis=1):对每行筛选出非零值的列名,组成元组作为模式标识(这是行级向量化操作,无显式for循环)。
  • pd.factorize:将唯一的模式映射为连续的数字编码,方便后续独热编码处理。
  • pd.get_dummies:将模式编码转换为独热矩阵,每行仅对应模式的列值为1,其余为0。
  • multiply(row_sums, axis=0):将独热矩阵与行总和按行相乘,自动将总和填充到对应模式的新列,其余列保持0。

运行代码后,输出结果完全符合你的需求,且全程无显式for循环,充分利用了Pandas的向量化效率优势。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:03:24