2017-01-04 3 views
2

, например, у меня есть dataframe с этими 2 колонками a и b:панды dataframe фильтрации строки, как GroupBy

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

Я ожидал отфильтрованный dataframe: [5,6,7,2,3,4,9,0,1]

без использования функции groupby (потому что это занимает слишком много времени с очень большим dataframe, это просто неприменимо), как я могу фильтровать последние 3 элемента из каждой группы в столбце. a?

ответ

2

подход # 1: Вот на основе NumPy подход -

In [89]: 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,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1]) 
    ...: 

In [90]: idx = np.append(np.nonzero(a[1:] > a[:-1])[0], a.size-1)[:,None] - [2,1,0] 

In [91]: b[idx].ravel() 
Out[91]: array([5, 6, 7, 2, 3, 4, 9, 0, 1]) 

Если вы повторно ceiving те из столбцов dataframe, df имени a и b соответственно, на стадии предварительной обработки, мы должны извлечь те, как массивы, как так -

a = df.a.values 
b = df.b.values 

Пожалуйста, обратите внимание, что это предполагает, по меньшей мере, три элемента за группу. Для случаев с меньшим, чем 3 elems на группу, читайте дальше к следующему подходу.


Подход № 2: С Scipy's binary dilation создать маску для выбора элементов от b -

from scipy.ndimage.morphology import binary_dilation as imdilate 
def filter_lastN(a, b, N): 
    mask = np.zeros(a.size,dtype=bool) 
    mask[np.append(np.nonzero(a[1:] > a[:-1])[0],b.size-1)] = 1 
    return b[imdilate(mask,np.ones(N),origin=(N-1)//2)] 

Пример запуска -

In [198]: a 
Out[198]: array([1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]) 

In [199]: b 
Out[199]: array([5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]) 

In [200]: filter_lastN(a,b,3) 
Out[200]: array([5, 6, 7, 2, 3, 4, 9, 0, 1]) 

In [201]: filter_lastN(a,b,5) 
Out[201]: array([5, 6, 7, 0, 1, 2, 3, 4, 7, 8, 9, 0, 1]) 
+0

подход 2 удивительно спасибо большое –

2

Вы можете использовать drop_duplicates первый за последние ряды groups, а затем получить предыдущие значения индекса и последний выбор по loc:

a = [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3] 
b = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1] 
df = pd.DataFrame({'a': a, 'b':b}) 
print (df) 
    a b 
0 1 1 
1 1 2 
2 1 3 
3 1 4 
4 1 5 
5 1 6 
6 1 7 
7 2 8 
8 2 9 
9 2 0 
10 2 1 
11 2 2 
12 2 3 
13 2 4 
14 3 5 
15 3 6 
16 3 7 
17 3 8 
18 3 9 
19 3 0 
20 3 1 
df1 = df.drop_duplicates('a',keep='last') 
print (df1) 
    a b 
6 1 7 
13 2 4 
20 3 1 

idx = sorted(df1.index.tolist() + (df1.index - 1).tolist() + (df1.index - 2).tolist()) 
print (idx) 
[4, 5, 6, 11, 12, 13, 18, 19, 20] 

print (df.loc[idx]) 
    a b 
4 1 5 
5 1 6 
6 1 7 
11 2 2 
12 2 3 
13 2 4 
18 3 9 
19 3 0 
20 3 1 
Смежные вопросы