我有一个包含许多属性的数据框。我想为这些属性的所有唯一组合分配一个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行)。数据管理员是否看到了解决我问题的不同方法?
非常感谢!
答案 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}}