本文介绍一种高效方法:基于每组连续 `1` 的实际长度,动态分配等距递增的百分比值(如 4 个 `1` 则分配 `[50, 66, 83, 100]`),确保末位恒为 100%,并自动将 `target=0` 行置零。
在使用 P

我们不预先固定步长,而是:
import pandas as pd
import numpy as np
# 示例数据
df = pd.DataFrame({
'ID': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
'TARGET': [1, 1, 1, 1, 0, 0, 0, 0]
})
# 步骤1:识别连续的1段(关键!)
df['block_id'] = (df['TARGET'] == 0).cumsum() # TARGET=0 时递增,形成连续1段的唯一标识
df['is_one'] = df['TARGET'] == 1
# 过滤出所有1的位置,并标记其所属连续段
ones_df = df[df['is_one']].copy()
ones_df['segment'] = (ones_df['block_id'] != ones_df['block_id'].shift()).cumsum()
# 步骤2:预定义完整百分比序列(MAX_ONES=6)
MAX_ONES = 6
PCTS = [int((100 / MAX_ONES) * n) for n in range(1, MAX_ONES + 1)] # [16,33,50,66,83,100]
# 步骤3:按连续段分组,为每段分配后缀序列
def assign_percentage(group):
k = len(group)
# 取PCTS后k个值(保证末位为100)
values = PCTS[-k:] if k <= MAX_ONES else PCTS
return pd.Series(values, index=group.index)
# 应用到ones_df
ones_df['PERCENTAGE'] = ones_df.groupby('segment').apply(assign_percentage).explode().astype(int)
# 步骤4:合并回原df,缺失处填0
df = df.merge(ones_df[['PERCENTAGE']], left_index=True, right_index=True, how='left')
df['PERCENTAGE'] = df['PERCENTAGE'].fillna(0).astype(int)
print(df[['ID', 'TARGET', 'PERCENTAGE']])该方案摆脱了固定步长的限制,通过预计算+后缀截取策略,确保任意长度的连续 1 序列都能生成以 100% 结尾的等差百分比列。结合连续段识别与向量化操作,兼具可读性与执行效率,是处理此类“动态归一化进度条”场景的推荐实践。