Срез DataFrame с использованием индексов из других столбцов - PullRequest
0 голосов
/ 11 декабря 2018

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

index   value   idxmin  idxmax
0       300     nan     nan
1       200     nan     nan
2       100     nan     nan
3       200     0       2
4       300     1       2
5       400     1       3
6       500     2       5
7       600     4       5
8       700     4       7
9       800     5       8
10      900     5       8
11      800     7       9
12      700     8       10
13      600     10      12
14      500     12      13
15      400     12      14
16      500     12      15
17      400     13      15
18      500     13      16
19      600     15      17
20      700     15      19

Я хочу создать новый столбец (maxvalue), который бы возвращал максимум столбца "value" для диапазона строк.Пример: для строки 9 максимальное значение «value» из строк 5–8 равно 800.

Я создал этот код, который фактически выполняется, но не эффективен

df['maxvalue'] = df.apply(lambda x : (df['value'].loc[x['idxmin']:x['idxmax']].max(), axis=1)

У вас есть более эффективный код для выполнения этой функции?

Ожидаемый результат (последний столбец):

index   value   idxmin  idxmax  maxvalue
0       300     nan     nan     nan
1       200     nan     nan     nan
2       100     nan     nan     nan
3       200     0       2       300
4       300     1       2       200
5       400     1       3       200
6       500     2       5       400
7       600     4       5       400
8       700     4       7       600
9       800     5       8       700
10      900     5       8       700
11      800     7       9       800
12      700     8       10      900
13      600     10      12      900
14      500     12      13      700
15      400     12      14      700
16      500     12      15      700
17      400     13      15      600
18      500     13      16      600
19      600     15      17      500
20      700     15      19      600

Большое спасибо за вашу помощь!!

1 Ответ

0 голосов
/ 11 декабря 2018

Эту операцию по своей природе сложно векторизовать, поскольку массив не отсортирован, а индексы, по-видимому, не представляют диапазоны одинакового размера.Я могу предложить превратить это в понимание списка, чтобы обойти накладные расходы с apply, но после этого вы сами.

df['maxvalue'] = [
    df['value'].values[int(s):int(e)].max() if pd.notna([s,e]).all() 
    else np.nan for s, e in zip(df['idxmin'], df['idxmax'])
]

df.head()
    index  value  idxmin  idxmax  maxvalue
0       0    300     NaN     NaN       NaN
1       1    200     NaN     NaN       NaN
2       2    100     NaN     NaN       NaN
3       3    200     0.0     2.0     300.0
4       4    300     1.0     2.0     200.0

ВДля того, чтобы извлечь из этого максимум пользы, необходимо перенести как можно больше тяжелой работы с панд на болванку.Я вижу ускорение в 15 раз на моей машине только на небольшом DataFrame с 1000 строками.

df_ = df
df = pd.concat([df_] * 1000, ignore_index=True)

%timeit df.apply(
    lambda x: df['value'].loc[x['idxmin']:x['idxmax']].max(), axis=1)
%%timeit 
[
    df['value'].values[int(s):int(e)].max() if pd.notna([s,e]).all() 
    else np.nan for s, e in zip(df['idxmin'], df['idxmax'])
]

4.79 s ± 68.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
268 ms ± 3.74 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...