2017-01-16 7 views
1

Wie kann ich den Wert der ersten Zeile in Spalte b und die letzte Zeile in Spalte b von Gruppierung nach Spalte a vergleichen, ohne die groupby Funktion zu verwenden? Weil die groupby-Funktion für einen großen Datensatz sehr langsam ist.pandas dataframe erste und letzte Zeile jeder Gruppe vergleichen

a = [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3] 
b = [1,0,0,0,0,0,7,8,0,0,0,0,0,4,1,0,0,0,0,0,1] 

Return zwei Listen: eine mit den Gruppennamen aus col hat a wobei der letzte Wert, der größer als der erste Wert ist, usw.

larger_or_equal = [1,3] 
smaller = [2] 
+0

Ich weiß, ich habe eine Antwort für diese, wenn ich nur die Frage verstanden. Kannst du etwas mehr arbeiten, um zu erklären, worüber du redest? – piRSquared

+0

Haben Sie versucht 'groupby (sort = False)'? Dies kann mit einem großen Dataset beschleunigen. – IanS

+0

@piRSquared, Gruppen '1' und' 3' werden ausgewählt, weil das letzte Element in der Gruppe größer oder gleich dem ersten ist. – IanS

Antwort

4

Alle numpy

a = np.array([1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3]) 
b = np.array([1,0,0,0,0,0,7,8,0,0,0,0,0,4,1,0,0,0,0,0,1]) 

w = np.where(a[1:] != a[:-1])[0] # find the edges 
e = np.append(w, len(a) - 1) # define the end pos 
s = np.append(0, w + 1) # define start pos 

# slice end pos with boolean array. then slice groups with end postions. 
# I could also have used start positions. 
a[e[b[e] >= b[s]]] 
a[e[b[e] < b[s]]] 

[1 3] 
[2] 
+0

Sollte schneller sein, denke ich! – IanS

+0

Ich habe es nicht getestet, aber ich nehme an, das ist 'True' – piRSquared

3

Hier ist eine Lösung ohne groupby. Die Idee ist, Spalte zu verschieben a Gruppe Änderungen zu erkennen:

df[df['a'].shift() != df['a']] 

    a b 
0 1 1 
7 2 8 
14 3 1 

df[df['a'].shift(-1) != df['a']] 

    a b 
6 1 7 
13 2 4 
20 3 1 

Wir werden die Spalte b in diesen beiden Datenrahmen vergleichen. Wir müssen einfach den Index zurücksetzen für die Pandas Vergleich zu arbeiten:

first = df[df['a'].shift() != df['a']].reset_index(drop=True) 
last = df[df['a'].shift(-1) != df['a']].reset_index(drop=True) 
first.loc[last['b'] >= first['b'], 'a'].values 

array([1, 3]) 

dann das Gleiche tun mit < die anderen Gruppen zu erhalten. Oder mache einen festen Unterschied.


Wie ich in den Kommentaren schrieb, groupby(sort=False) gut könnte schneller sein, je nach Datenmenge.

Verwandte Themen