2017-01-09 37 views
3

考虑数据框df排序数据帧由组的位置,然后由该组

df = pd.DataFrame(dict(
     A=list('aaaaabbbbccc'), 
     B=range(12) 
    )) 

print(df) 

    A B 
0 a 0 
1 a 1 
2 a 2 
3 a 3 
4 a 4 
5 b 5 
6 b 6 
7 b 7 
8 b 8 
9 c 9 
10 c 10 
11 c 11 

我要排序的数据帧,例如,如果我通过'A'列编组我拉各组第一的位置,然后循环如果有剩余的话,从每个组中获得第二个位置。等等等等。

我期望的结果TOT这个样子

A B 
0 a 0 
5 b 5 
9 c 9 
1 a 1 
6 b 6 
10 c 10 
2 a 2 
7 b 7 
11 c 11 
3 a 3 
8 b 8 
4 a 4 

回答

4

可以使用cumcount的计数值在groups,再sort_valuesreindex通过Seriescum

cum = df.groupby('A')['B'].cumcount().sort_values() 
print (cum) 
0  0 
5  0 
9  0 
1  1 
6  1 
10 1 
2  2 
7  2 
11 2 
3  3 
8  3 
4  4 
dtype: int64 

print (df.reindex(cum.index)) 
    A B 
0 a 0 
5 b 5 
9 c 9 
1 a 1 
6 b 6 
10 c 10 
2 a 2 
7 b 7 
11 c 11 
3 a 3 
8 b 8 
4 a 4 
2

这里有一个NumPy的方法 -

def approach1(g, v): 
    # Inputs : 1D arrays of groupby and value columns 
    id_arr2 = np.ones(v.size,dtype=int) 
    sf = np.flatnonzero(g[1:] != g[:-1])+1 
    id_arr2[sf[0]] = -sf[0]+1 
    id_arr2[sf[1:]] = sf[:-1] - sf[1:]+1 
    return id_arr2.cumsum().argsort(kind='mergesort') 

采样运行 -

In [246]: df 
Out[246]: 
    A B 
0 a 0 
1 a 1 
2 a 2 
3 a 3 
4 a 4 
5 b 5 
6 b 6 
7 b 7 
8 b 8 
9 c 9 
10 c 10 
11 c 11 

In [247]: df.iloc[approach1(df.A.values, df.B.values)] 
Out[247]: 
    A B 
0 a 0 
5 b 5 
9 c 9 
1 a 1 
6 b 6 
10 c 10 
2 a 2 
7 b 7 
11 c 11 
3 a 3 
8 b 8 
4 a 4 
@jezrael's post

或者使用df.reindex

df.reindex(approach1(df.A.values, df.B.values))