2017-01-09 1 views
3

betrachten die Datenrahmen dfArt Datenrahmen von Position in der Gruppe dann von dieser Gruppe

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 

Ich möchte die Datenrahmen so sortieren, wenn ich nach Spalte gruppiert 'A' ich aus jeder Gruppe die erste Position ziehen würde, dann Zyklus zurück und holen Sie sich die zweite Position aus jeder Gruppe, falls noch welche übrig sind. Und so weiter und so fort.

Ich würde erwarten, dass Ergebnisse wie diese können

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 

Antwort

4

Sie cumcount in groups für Zählwerte verwenden tot sehen zuerst, dann sort_values und reindex von 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

Hier ist ein NumPy Ansatz -

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') 

Probelauf -

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 

Oder df.reindex von @jezrael's post mit:

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