使用groupby()时,如何使用包含组编号索引的新列创建DataFrame,类似于dplyr::group_indices
R中.例如,如果我有
>>> df=pd.DataFrame({'a':[1,1,1,2,2,2],'b':[1,1,2,1,1,2]}) >>> df a b 0 1 1 1 1 1 2 1 2 3 2 1 4 2 1 5 2 2
我怎么能得到一个像DataFrame
a b idx 0 1 1 1 1 1 1 1 2 1 2 2 3 2 1 3 4 2 1 3 5 2 2 4
(idx
索引的顺序无关紧要)
一种简单的方法是连接分组列(以便它们的每个值组合代表一个独特的不同元素),然后将其转换为pandas Categorical并仅保留其标签:
df['idx'] = pd.Categorical(df['a'].astype(str) + '_' + df['b'].astype(str)).codes df a b idx 0 1 1 0 1 1 1 0 2 1 2 1 3 2 1 2 4 2 1 2 5 2 2 3
编辑:更改labels
属性,codes
因为前者似乎已被弃用
Edit2:根据Authman Apatira的建议添加了一个分隔符
这是一种使用drop_duplicates
和merge
获取唯一标识符的简洁方法.
group_vars = ['a','b'] df.merge( df.drop_duplicates( group_vars ).reset_index(), on=group_vars ) a b index 0 1 1 0 1 1 1 0 2 1 2 2 3 2 1 3 4 2 1 3 5 2 2 5
在这种情况下,标识符为0,2,3,5(只是原始索引的残差),但这可以很容易地更改为0,1,2,3 reset_index(drop=True)
.
下面是使用该解决方案ngroup
由一个评论上述由君士坦丁,对于那些仍在寻找这个功能(相当于dplyr::group_indices
在R,如果你想与我一样这些关键字,谷歌).根据我自己的时间,这也比maxliving给出的解决方案快约25%.
>>> import pandas as pd >>> df = pd.DataFrame({'a':[1,1,1,2,2,2],'b':[1,1,2,1,1,2]}) >>> df['idx'] = df.groupby(['a', 'b']).ngroup() >>> df a b idx 0 1 1 0 1 1 1 0 2 1 2 1 3 2 1 2 4 2 1 2 5 2 2 3 >>> %timeit df['idx'] = create_index_usingduplicated(df, grouping_cols=['a', 'b']) 1.83 ms ± 67.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) >>> %timeit df['idx'] = df.groupby(['a', 'b']).ngroup() 1.38 ms ± 30 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)