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

Pandas中按优先级统计唯一CUS_NO值:优先统计both指标

问题解决:按规则统计唯一CUS_NO数量

原始数据与需求

先定义原始的Pandas DataFrame:

import pandas as pd
import numpy as np
df = pd.DataFrame({'CUS_NO': ['900636229', '900636229', '900636080', '900636080', '900636052', '900636052', 
                              '900636053', '900636054', '900636055', '900636056'], 
                   'indicator': ['both', 'left_only', 'both', 'left_only', 'both', 'left_only', 
                                 'both', 'left_only', 'both', 'left_only'],
                   'Nationality': ['VN', 'VN', 'KR', 'KR', 'VN', 'VN', 
                                   'KR', 'VN', 'KR', 'VN']})

需求是统计唯一CUS_NO的数量,核心规则:同一CUS_NO同时对应both和left_only时,仅在both列统计,left_only列不统计该编号。

原始使用pivot_table的方法会将同时存在两种indicator的CUS_NO在两列都统计,不符合需求,需要调整处理逻辑。

实现方法

方案1:先标记归属再统计(高效简洁)

直接从每个CUS_NO的维度确定其最终统计归属,再进行分组统计:

# 按CUS_NO分组,获取每个编号的国籍和对应的indicator集合
cus_info = df.groupby('CUS_NO').agg(
    Nationality=('Nationality', 'first'),
    indicators=('indicator', set)
).reset_index()

# 给每个编号分配最终统计列:包含both则归为both,否则归为left_only
cus_info['final_indicator'] = cus_info['indicators'].apply(lambda x: 'both' if 'both' in x else 'left_only')

# 分组统计唯一CUS_NO数量
df_result = cus_info.groupby(['Nationality', 'final_indicator'])['CUS_NO'].nunique().unstack(fill_value=0)

# 添加All汇总行和列
df_result['All'] = df_result.sum(axis=1)
df_result.loc['All'] = df_result.sum(axis=0)

# 重置索引得到目标格式
df_result = df_result.reset_index()

方案2:预处理数据集后透视统计

先筛选出符合各列统计规则的样本,再进行透视:

# 标记每个CUS_NO是否包含both类型
df['has_both'] = df.groupby('CUS_NO')['indicator'].transform(lambda x: 'both' in x.values)
# 筛选仅属于left_only的CUS_NO(无both记录)
only_left = df.groupby('CUS_NO')['indicator'].transform(lambda x: x.nunique() == 1 and x.iloc[0] == 'left_only')

# 分别提取符合both和left_only统计规则的记录
df_both = df[df['has_both']].copy()
df_both['indicator'] = 'both'
df_left = df[only_left].copy()

# 合并处理后的数据集
processed_df = pd.concat([df_both, df_left], ignore_index=True)

# 透视统计并补充汇总项
df_result = pd.pivot_table(processed_df, values='CUS_NO', 
                           index='Nationality', 
                           columns='indicator', 
                           aggfunc=pd.Series.nunique, 
                           fill_value=0,
                           margins=True).reset_index()

两种方案最终都会得到符合需求的结果:

indicator   Nationality  both  left_only  All
0           KR           3     0          3
1           VN           2     2          4
2           All          5     2          7

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:23:21