2017-01-16 3 views
1

Как сравнить значение первой строки в седловине b и последней строки в седловине b из группировки по седловине a, без использования функции groupby? Потому что функция groupby очень медленная для большого набора данных.панды dataframe сравнить первую и последнюю строку из каждой группы

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] 

Возврат два списка: один имеет названия групп из седловины a где последнее значение больше, чем первое значение, и т.д.

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

Я знаю, что у меня есть ответ на это, если я просто понял вопрос. Можете ли вы сделать немного больше работы, объясняя, о чем вы говорите? – piRSquared

+0

Вы пробовали 'groupby (sort = False)'? Это может ускорить работу с большим набором данных. – IanS

+0

@piRSquared, группы '1' и' 3' выбраны, потому что последний элемент в группе больше или равен первому. – IanS

ответ

4

Все 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

Должно быть быстрее, я думаю! – IanS

+0

Я не тестировал его, но я предполагаю, что это 'True' – piRSquared

3

Вот решение без groupby. Идея заключается в том, чтобы переместить столбец a для обнаружения изменений группы:

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 

Мы будем сравнивать столбец b в этих двух dataframes. Нам просто нужно сбросить индекс для сравнения панды работы:

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

Затем сделайте то же самое с <, чтобы получить другие группы. Или сделайте разницу в настройках.


Как я уже писал в комментариях, groupby(sort=False) вполне может быть быстрее, в зависимости от набора данных.