разделить фрейм данных, если число меньше предыдущего - PullRequest
0 голосов
/ 09 мая 2018

У меня есть серия, подобная этой: test = pd.Series([2.4,5.6,8.8,25.6,53.6,1.7,5.7,8.9])

Я хочу разбить его на две серии в той точке, где следующее число будет меньше предыдущего. Это происходит только один раз в любой серии, но это не происходит в надежном месте (может быть 7-е место, 4-е место и т. Д.).

Результат должен выглядеть следующим образом:

test1
2.4
5.6
8.8
25.6
53.6

и

test2
1.7
5.7
8.9

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Вы можете сделать это так:

for n,g in test.groupby(test.diff().lt(0).cumsum()):
    print(g)
    print("\n")

Выход:

0     2.4
1     5.6
2     8.8
3    25.6
4    53.6
dtype: float64


5    1.7
6    5.7
7    8.9
dtype: float64

Как @AntonvBR предлагает:

test1, test2 = (i for _, i in test.groupby(test.diff().lt(0).cumsum()))
0 голосов
/ 09 мая 2018

Могли бы заархивироваться на генератор и использовать дальше. Затем мы используем np.split и отображаем на pd.Series. Должно быть быстро:

import pandas as pd
import numpy as np

test = pd.Series([2.4,5.6,8.8,25.6,53.6,1.7,5.7,8.9])

i = next(ind for ind, v in enumerate(zip(test,test[1:])) if v[0] > v[1])
test1, test2 = map(pd.Series,np.split(test, [i+1]))

Или напишите в «однострочный» как:

test1, test2 = map(pd.Series,
                   np.split(test, [next((ind for ind, v in enumerate(zip(test,test[1:])) 
                                         if v[0] > v[1])+1, None)]))

Сравнение времени:

%timeit map(pd.Series,np.split(test, [next((ind for ind, v in enumerate(zip(test,test[1:])) if v[0] > v[1]), None) + 1]))
%timeit (i for _, i in test.groupby(test.diff().lt(0).cumsum()))
%timeit map(pd.Series,np.split(test, [(test - test.shift(-1)).idxmax() + 1]))

Результаты:

#1000 loops, best of 3: 237 µs per loop  <- Anton vbr
#1000 loops, best of 3: 599 µs per loop  <- Scott Boston
#1000 loops, best of 3: 392 µs per loop  <- Ami Tavory
0 голосов
/ 09 мая 2018

Вы можете найти позицию с помощью

pos = (test - test.shift(-1)).argmax()

Теперь сериал пока что

>>> test[: pos + 1]
0     2.4
1     5.6
2     8.8
3    25.6
4    53.6
dtype: float64

Аналогично, остаток составляет

>>> test[pos + 1: ]
5    1.7
6    5.7
7    8.9
dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...