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

使用Pandas将数据集过滤为retention1、retention2及混合留存数据框的方案

前置数据预处理

先统一清洗数据,生成后续要用的判断标记:

import pandas as pd
# 统一替换字符串None为真实空值
df = df.replace({'None': None})
# 生成每行的r1/r2非空标记
df['has_r1'] = df['retention1'].notna()
df['has_r2'] = df['retention2'].notna()

分类逻辑实现

先按name分组判断每个name所属的留存类型:

# 分组聚合判断每个name的类型标记
name_type = df.groupby('name').agg(
    has_any_r1=('has_r1', 'any'),
    has_any_r2=('has_r2', 'any')
).reset_index()
# 打类型标签
name_type['retention_type'] = '混合留存'
name_type.loc[(name_type['has_any_r1']==True) & (name_type['has_any_r2']==False), 'retention_type'] = 'retention1'
name_type.loc[(name_type['has_any_r1']==False) & (name_type['has_any_r2']==True), 'retention_type'] = 'retention2'
# 把类型标签合并回原表
df = df.merge(name_type[['name', 'retention_type']], on='name', how='left')

有效值提取通用逻辑

先写工具函数处理AZ_URL判断和retention值提取:

def get_element_index(cluster_id, az_url):
    # 按实际AZ_URL分隔符调整,这里默认用/或:拆分,取前两部分判断
    az_parts = az_url.replace(':', '/').split('/')[:2]
    if cluster_id in az_parts[1]:
        return 0 # 第二部分,取第一个元素
    elif cluster_id in az_parts[0]:
        return 1 # 第一部分,取第二个元素
    # 匹配不到的情况可根据业务补默认值
    return 0

def extract_retention_value(retention_str, idx):
    if pd.isna(retention_str):
        return None
    # 去除括号,按分号拆分
    parts = retention_str.strip('[]').split(';')
    return parts[idx].strip() if len(parts) > idx else None

分类型计算最终值

1. retention1类型计算

r1_df = df[df['retention_type'] == 'retention1'].copy()
# 计算取值索引
r1_df['elem_idx'] = r1_df.apply(lambda x: get_element_index(x['ClusterID'], x['Az_URL']), axis=1)
# 提取retention1有效值
r1_df['final_retention'] = r1_df.apply(lambda x: extract_retention_value(x['retention1'], x['elem_idx']), axis=1)

2. retention2类型计算

r2_df = df[df['retention_type'] == 'retention2'].copy()
# 计算取值索引
r2_df['elem_idx'] = r2_df.apply(lambda x: get_element_index(x['ClusterID'], x['Az_URL']), axis=1)
# 分别提取retention2数值和快照留存类型
r2_df['final_retention'] = r2_df.apply(lambda x: extract_retention_value(x['retention2'], x['elem_idx']), axis=1)
r2_df['final_snapshot'] = r2_df.apply(lambda x: extract_retention_value(x['retention snapshot'], x['elem_idx']), axis=1)

3. 混合留存类型计算

混合留存可直接保留分组内的所有有效记录,或按业务需要聚合输出:

mix_df = df[df['retention_type'] == '混合留存'].copy()
# 同样按规则提取每条有效记录的对应值即可
mix_df['elem_idx'] = mix_df.apply(lambda x: get_element_index(x['ClusterID'], x['Az_URL']), axis=1)
mix_df['final_r1'] = mix_df.apply(lambda x: extract_retention_value(x['retention1'], x['elem_idx']) if x['has_r1'] else None, axis=1)
mix_df['final_r2'] = mix_df.apply(lambda x: extract_retention_value(x['retention2'], x['elem_idx']) if x['has_r2'] else None, axis=1)
mix_df['final_snapshot'] = mix_df.apply(lambda x: extract_retention_value(x['retention snapshot'], x['elem_idx']) if x['has_r2'] else None, axis=1)

原有代码问题说明

  1. retention2计算的两行str.extract逻辑错误,第一行提取数字后第二行又提取字母会直接覆盖原有结果,需要分开存储数值和快照类型
  2. 混合留存的groupby.agg写法语法错误,lambda参数不能直接写x['retention1'],需要先按分组判断类型再处理对应字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 17:45:03