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

如何基于Pandas布尔行生成含规则字符串的新列?

问题描述

我有一个包含多列布尔值/整数(1/0)的Pandas DataFrame,需要生成新结果列,其字符串按规则构建:统计连续True值的组数、是否中断、起止列及True值总数。

示例DataFrame如下:

column_1  column_2  column_3  column_4  column_5  column_6  column_7  column_8  column_9  column_10 
0          0         1         0         1         1         1         1         0         0          1
1          0         1         1         0         1         1         1         0         0          1
2          1         1         0         0         0         1         1         0         0          1
3          1         1         1         0         0         0         0         1         1          1
4          1         1         1         0         0         1         0         0         1          1
5          1         1         1         0         0         0         1         1         0          1
6          0         1         1         1         1         1         1         0         1          0

结果字符串分为四个片段,以/分隔:

  • 首段:i表示存在中断(连续True值组之间有0分隔),c表示无中断;数字为连续True值≥2的组数。
  • 第二段:各组连续True值的长度,多组用-分隔。
  • 第三段:各组连续True值的起止列编号(列名后缀数字),多组用_分隔,组内起止用-连接。
  • 第四段:该行所有True值(1)的总数。

示例:

  • 第1行[0 1 1 0 1 1 1 0 0 1]的结果字符串为i2/2-3/c2-c3_c5-c7/6
  • 第6行[0 1 1 1 1 1 1 0 1 0]的结果字符串为c1/6/c2-c7/7

初始代码如下:

import pandas as pd
import numpy as np

def create_custom_result(df: pd.DataFrame) -> pd.Series:
    return df

def create_dataframe() -> pd.DataFrame:
    df = pd.DataFrame()  # empty df

    for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:   # create random bool/int values
        df[f'column_{i}'] = np.random.randint(2, size=50)

    df["column_result"] = ''    # add result column
    return df

if __name__=="__main__":
    df = create_dataframe()
    custom_results = create_custom_result(df=df)

尝试过逐行遍历,但不知如何构建结果字符串;查找的资料多为列的连续值处理,而非行横向处理,希望得到该需求的实现方案。


解决方案

核心思路是对每一行横向遍历,识别连续的1序列,记录每组的长度、起止列号,再按规则拼接结果字符串。以下是实现代码:

import pandas as pd
import numpy as np

def create_custom_result(df: pd.DataFrame) -> pd.Series:
    # 提取列名对应的数字编号(column_1对应1)
    col_numbers = [int(col.split('_')[1]) for col in df.columns]
    
    def process_row(row):
        groups = []  # 存储连续1的组:(起始列号, 结束列号)
        current_start = None
        
        # 遍历行内每个值和对应列号
        for val, col_num in zip(row, col_numbers):
            if val == 1:
                if current_start is None:
                    current_start = col_num
            else:
                if current_start is not None:
                    # 结束一个连续组
                    groups.append((current_start, col_num - 1))
                    current_start = None
        # 处理行末尾未结束的连续组
        if current_start is not None:
            groups.append((current_start, col_numbers[-1]))
        
        # 筛选出长度≥2的有效组
        valid_groups = [g for g in groups if g[1] - g[0] + 1 >= 2]
        valid_count = len(valid_groups)
        
        # 判断是否中断:有效组数量>1 或 总1数>有效组总长度(存在单独的1)
        total_ones = row.sum()
        valid_total = sum(end - start + 1 for start, end in valid_groups)
        has_interrupt = valid_count > 1 or (total_ones > valid_total)
        
        # 构建各片段
        segment1 = f'{"i" if has_interrupt else "c"}{valid_count}'
        segment2 = '-'.join([str(end - start + 1) for start, end in valid_groups]) if valid_groups else ''
        segment3 = '_'.join([f'c{start}-c{end}' for start, end in valid_groups]) if valid_groups else ''
        segment4 = str(total_ones)
        
        # 拼接结果字符串
        return '/'.join([segment1, segment2, segment3, segment4])
    
    # 逐行处理生成结果序列
    return df.apply(process_row, axis=1)

def create_dataframe() -> pd.DataFrame:
    df = pd.DataFrame()  # empty df

    for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:   # create random bool/int values
        df[f'column_{i}'] = np.random.randint(2, size=50)

    df["column_result"] = ''    # add result column
    return df

if __name__=="__main__":
    # 用示例数据测试
    sample_data = [
        [0,1,0,1,1,1,1,0,0,1],
        [0,1,1,0,1,1,1,0,0,1],
        [1,1,0,0,0,1,1,0,0,1],
        [1,1,1,0,0,0,0,1,1,1],
        [1,1,1,0,0,1,0,0,1,1],
        [1,1,1,0,0,0,1,1,0,1],
        [0,1,1,1,1,1,1,0,1,0]
    ]
    df = pd.DataFrame(sample_data, columns=[f'column_{i}' for i in range(1,11)])
    df["column_result"] = create_custom_result(df)
    print(df[["column_result"]])

代码说明

  1. 列编号提取:从列名中提取数字后缀,方便后续记录连续组的起止列号。
  2. 行处理逻辑:
    • 遍历行内每个值,识别连续的1序列,记录每个组的起止列号。
    • 筛选出长度≥2的有效组,统计其数量。
    • 通过有效组数量和总1数的关系判断是否存在中断。
    • 分别构建四个结果片段,最终用/拼接成完整字符串。
  3. 批量处理:用apply函数将行处理逻辑应用到DataFrame的每一行,生成结果列。

测试示例数据时,会输出符合要求的结果,比如第1行返回i2/2-3/c2-c3_c5-c7/6,第6行返回c1/6/c2-c7/7。

内容的提问来源于stack exchange,提问作者Wicked Gummy Bear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:45:18