как выбрать последнее значение в методе groupby - PullRequest
2 голосов
/ 28 января 2020

У меня есть фрейм данных

col1
 1
 2
 3
 4
 5
 6
 7

Я хочу выбирать и транслировать последний элемент каждые 3 строки, и желаемый результат:

col1  col2
 1      3
 2      3
 3      3
 4      6
 5      6
 6      6
 7      7

Я пытался

df['col2'] = df['col1'].groupby(np.arange(len(df))//3).transform(lambda x: x.loc[-1])

Но это продолжалось долго.

1 Ответ

1 голос
/ 28 января 2020

Первая идея - использовать GroupBy.last лямбда-функция intead:

df['col21'] = df['col1'].groupby(np.arange(len(df))//3).transform('last')

Если все еще необходимо улучшить производительность, используйте numpy решение с np.repeat:

arr = df['col1'].to_numpy()
arr1 = np.repeat(arr[2::3], 3)
lenght = len(arr) % 3
arr2 = np.repeat(arr[-1:], lenght)
df['col22'] = np.concatenate([arr1, arr2]).astype(int)
print (df)
   col1  col21  col22
0     1      3      3
1     2      3      3
2     3      3      3
3     4      6      6
4     5      6      6
5     6      6      6
6     7      7      7

Производительность :

#[70000 rows x 1 columns]
df = pd.concat([df] * 10000, ignore_index=True)

In [122]: %%timeit
     ...: df['col20'] = df['col1'].groupby(np.arange(len(df))//3).transform(lambda x: x.iloc[-1])
     ...: 
7.61 s ± 356 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [123]: %%timeit
     ...: df['col21'] = df['col1'].groupby(np.arange(len(df))//3).transform('last')
     ...: 
     ...: 
7.28 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [124]: %%timeit
     ...: arr = df['col1'].to_numpy()
     ...: arr1 = np.repeat(arr[2::3], 3)
     ...: lenght = len(arr) % 3
     ...: arr2 = np.repeat(arr[-1:], lenght)
     ...: df['col22'] = np.concatenate([arr1, arr2]).astype(int)
     ...: 
850 µs ± 18.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...