Pandas - 为分组数据中的每个组分配唯一ID

时间:2018-01-29 16:28:13

标签: python pandas numpy dataframe

我有一个包含许多属性的数据框。我想为这些属性的所有唯一组合分配一个id。

假设,这是我的df:

df = pd.DataFrame(np.random.randint(1,3, size=(10, 3)), columns=list('ABC'))

   A  B  C
0  2  1  1
1  1  1  1
2  1  1  1
3  2  2  2
4  1  2  2
5  1  2  1
6  1  2  2
7  1  2  1
8  1  2  2
9  2  2  1

现在,我需要添加一个带有唯一组合ID的新列。它必须为0,组合只发生一次。在这种情况下:

   A  B  C  unique_combination
0  2  1  1  0
1  1  1  1  1
2  1  1  1  1
3  2  2  2  0
4  1  2  2  2
5  1  2  1  3
6  1  2  2  2
7  1  2  1  3
8  1  2  2  2
9  2  2  1  0

我的第一种方法是使用for循环并检查每一行,如果我在.query的行的数据框中找到多个组合:

unique_combination = 1 #acts as a counter
df['unique_combination'] = 0    

for idx, row in df.iterrows():
    if len(df.query('A == @row.A & B == @row.B & C == @row.C')) > 1:
        # check, if one occurrence of the combination already has a value > 0???
        df.loc[idx, 'unique_combination'] = unique_combination
        unique_combination += 1

但是,我不知道如何检查是否已为组合分配了ID(请参阅代码中的注释)。此外,我的方法感觉非常缓慢和hacky(我有超过15000行)。数据管理员是否看到了解决我问题的不同方法?

非常感谢!

2 个答案:

答案 0 :(得分:4)

步骤1:分配值为0

的新列
df['new'] = 0

步骤2:创建重复次数超过1的掩码,即

mask = df.groupby(['A','B','C'])['new'].transform(lambda x : len(x)>1)

步骤3:根据掩码分配分解值,即

df.loc[mask,'new'] = df.loc[mask,['A','B','C']].astype(str).sum(1).factorize()[0] + 1

# or
# df.loc[mask,'new'] = df.loc[mask,['A','B','C']].groupby(['A','B','C']).ngroup()+1 

输出:

   A  B  C  new
0  2  1  1    0
1  1  1  1    1
2  1  1  1    1
3  2  2  2    0
4  1  2  2    2
5  1  2  1    3
6  1  2  2    2
7  1  2  1    3
8  1  2  2    2
9  2  2  1    0

答案 1 :(得分:0)

Pandas 0.20.2版中添加的一项新功能会自动为您创建一列唯一ID。

df['unique_id'] = df.groupby(['A', 'B', 'C']).ngroup()

给出以下输出

    A   B   C   unique_id
0   2   1   2   3
1   2   2   1   4
2   1   2   1   1
3   1   2   2   2
4   1   1   1   0
5   1   2   1   1
6   1   1   1   0
7   2   2   2   5
8   1   2   2   2
9   1   2   2   2

根据组的迭代顺序为其指定ID。

在此处查看文档:{​​{3}}