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

在Pandas中提取特定列值唯一的行并添加计数列

问题

我的DataFrame如下:

id        name      class
--------------------------
0        Nick        a
1        Jane        b
2        Jacon       a
3        Jack        b
4        Cooze       a
--------------------------
5        Nick        b
6        Jane        b
7        Jacon       c
8        Jack        a
9        Cooze       a
--------------------------
10       John        a

我需要提取所有在class列中值唯一的name,同时添加新列显示每个name-class组合的重复次数,最终结果如下:

id        name       class    count
-----------------------------------
0         Jane        b       2
1         Cooze       a       2
2         John        a       1

补充说明:John被纳入是因为它在name列中仅出现一次,因此其class列值唯一。

我已经尝试了以下代码:

data = {
    'name':  ['Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'John'],
    'class': ['a',    'b',     'a',    'b',    'a',     'b',    'b',    'c',     'a',    'a', 'a']}
df = pd.DataFrame(data)
new_data = df.groupby('name')['class'].unique()
print(new_data)

得到的输出:

name
Cooze       [a]
Jack     [b, a]
Jacon    [a, c]
Jane        [b]
John        [a]
Nick     [a, b]
Name: class, dtype: object

接下来我想获取每个class唯一值列表的长度,筛选出长度为1的项,但操作时出现多种错误,而且感觉可以有更简便的方法。作为Pandas新手,请问该如何实现需求?

解决方案

这里提供两种简洁高效的实现方法,核心是利用nunique()直接统计每个name对应的class唯一值数量,避免手动处理数组的麻烦:

方法一:先筛选有效name,再统计次数

  1. 先通过分组计算每个name的class唯一值数量,筛选出数量为1的name;
  2. 从原DataFrame中提取这些name的记录,再按name和class分组统计重复次数,最后整理成目标格式。

代码示例:

import pandas as pd

data = {
    'name':  ['Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'John'],
    'class': ['a',    'b',     'a',    'b',    'a',     'b',    'b',    'c',     'a',    'a', 'a']}
df = pd.DataFrame(data)

# 筛选出class值唯一的name
valid_names = df.groupby('name')['class'].nunique()[lambda x: x == 1].index

# 筛选记录、统计次数并整理格式
result = df[df['name'].isin(valid_names)] \
           .groupby(['name', 'class'], as_index=False) \
           .size() \
           .rename(columns={'size': 'count'}) \
           .reset_index(drop=True) \
           .rename_axis('id').reset_index()

print(result)

输出结果:

id    name class  count
0   0  Cooze     a      2
1   1   Jane     b      2
2   2   John     a      1

方法二:用transform标记后直接筛选统计

通过transform在原DataFrame的每行添加对应name的class唯一值数量,直接筛选符合条件的行后统计次数:

代码示例:

import pandas as pd

data = {
    'name':  ['Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'John'],
    'class': ['a',    'b',     'a',    'b',    'a',     'b',    'b',    'c',     'a',    'a', 'a']}
df = pd.DataFrame(data)

# 给每行标记对应name的class唯一值数量
df['class_unique_count'] = df.groupby('name')['class'].transform('nunique')

# 筛选、统计并整理格式
result = df[df['class_unique_count'] == 1] \
           .groupby(['name', 'class'], as_index=False) \
           .size() \
           .rename(columns={'size': 'count'}) \
           .reset_index(drop=True) \
           .rename_axis('id').reset_index()

print(result)

输出与方法一完全一致。

关键提示

  • nunique()是这里的核心,它直接返回分组后某列的唯一值数量,比你之前用的unique()更适合这个场景,省去了手动计算列表长度的步骤,避免操作数组时的错误;
  • 最后通过rename_axis('id').reset_index()生成目标中的id列,完美匹配需求格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 08:43:20