如何标记熊猫中的成对组?

Ame*_*tep 1 python python-2.7 pandas pandas-groupby

我有这个数据框:

>>> df = pd.DataFrame({'A': [1, 2, 1, np.nan, 2, 2, 2], 'B': [2, 1, 2, 2.0, 1, 1, 2]})
>>> df
     A    B
0  1.0  2.0
1  2.0  1.0
2  1.0  2.0
3  NaN  2.0
4  2.0  1.0
5  2.0  1.0
6  2.0  2.0
Run Code Online (Sandbox Code Playgroud)

我需要在第三列“组 ID”上识别成对 (A,B) 的组,以获得如下所示的内容:

>>> df
     A    B  grup id                        explanation
0  1.0  2.0      1.0  <- group (1.0, 2.0), first group 
1  2.0  1.0      2.0  <- group (2.0, 1.0), second group
2  1.0  2.0      1.0  <- group (1.0, 2.0), first group 
3  NaN  2.0      NaN  <- invalid group                 
4  2.0  1.0      2.0  <- group (2.0, 1.0), second group
5  2.0  1.0      2.0  <- group (2.0, 1.0), second group
6  2.0  2.0      3.0  <- group (2.0, 2.0), third group 
Run Code Online (Sandbox Code Playgroud)

我怎样才能在熊猫中有效地做到这一点?

一个想法是首先构建一个组合列 (A,B),然后识别该列中的唯一值并将它们映射回我的数据框。但我怀疑 groupby() 方法会更快(也更优雅)。

我试过这个:

>>> df.groupby(['A','B']).count()
Empty DataFrame
Columns: []
Index: [(1.0, 2.0), (2.0, 1.0), (2.0, 2.0)]
Run Code Online (Sandbox Code Playgroud)

所以这个 groupby() 的索引列出了我需要的所有组。但是如何计算它们并将它们映射回我的数据帧?

jez*_*ael 5

您可以使用GroupBy.ngroup(熊猫 0.20.2+):

print (df.groupby(['A','B']).ngroup())
0    0
1    1
2    0
3   -1
4    1
5    1
6    2
dtype: int64

df['grup id'] = df.groupby(['A','B']).ngroup().replace(-1,np.nan).add(1)
print (df)
     A    B  grup id
0  1.0  2.0      1.0
1  2.0  1.0      2.0
2  1.0  2.0      1.0
3  NaN  2.0      NaN
4  2.0  1.0      2.0
5  2.0  1.0      2.0
6  2.0  2.0      3.0
Run Code Online (Sandbox Code Playgroud)

类似于 replace-1和 add 1

df['grup id'] = df.groupby(['A','B']).ngroup()
df['grup id'] = np.where(df['grup id'] == -1, np.nan, df['grup id'] + 1)
print (df)
     A    B  grup id
0  1.0  2.0      1.0
1  2.0  1.0      2.0
2  1.0  2.0      1.0
3  NaN  2.0      NaN
4  2.0  1.0      2.0
5  2.0  1.0      2.0
6  2.0  2.0      3.0
Run Code Online (Sandbox Code Playgroud)

对于pandas(低于 0.20.2)的最旧版本:

df['grup id'] = df.groupby(["A","B"]).grouper.group_info[0]
df['grup id'] = np.where(df['grup id'] == -1, np.nan, df['grup id'] + 1)
print (df)
     A    B  grup id
0  1.0  2.0      1.0
1  2.0  1.0      2.0
2  1.0  2.0      1.0
3  NaN  2.0      NaN
4  2.0  1.0      2.0
5  2.0  1.0      2.0
6  2.0  2.0      3.0
Run Code Online (Sandbox Code Playgroud)