расширение операции с условием if - PullRequest
0 голосов
/ 26 сентября 2019

Допустим, у меня есть следующий фрейм данных.

df = pd.DataFrame([[1234,0,1],[1234,1,2],[1234,0,3],[2256,1,4],[1234,0,5],[1234,1,6],[1234,0,7],[2256,0,8],[2256,1,9],[2256,0,10]],columns=['ID','result','time'])

Пример

     ID  result  time
0  1234       0     1
1  1234       1     2
2  1234       0     3
3  2256       1     4
4  1234       0     5
5  1234       1     6
6  1234       0     7
7  2256       0     8
8  2256       1     9
9  2256       0     10
10 1234       1     11

Я хочу сгруппировать по ID.Затем я хотел бы добавить столбец «time_since_1» для каждого идентификатора.'time_since_1' - это длительность времени с тех пор, как результат стал 1 для каждого идентификатора.Время будет сброшено после результат каждого идентификатора становится равным 1. Так что мне также нужно смещение.

Требуемый выход

     ID  result  time time_since_1
0  1234       0     1            0  → Nothing hasn't happened yet
1  1234       1     2            0  → first time = 0 (ID = 1234)
2  1234       0     3            1  → 3-2 = 1        (ID = 1234)
3  2256       1     4            0  → first time = 0 (ID = 2256)
4  1234       0     5            3  → 5-2 = 3        (ID = 1234)
5  1234       1     6            4  → 6-2 = 4        (ID = 1234)  
6  1234       0     7            1  → 7-6 = 1        (ID = 1234)
7  2256       0     8            4  → 8-4 = 4        (ID = 2256) 
8  2256       1     9            5  → 9-4 = 5        (ID = 2256) 
9  2256       0     10           1  → 10-9 = 1       (ID = 2256)
10 1234       1     11           5  → 11-6 = 5       (ID = 1234) 

Я попытался создать код, и в итоге обнаружил, что .expanding () может помочь в этом случае.Итак, я попробовал приведенный ниже код.

df['time_since_1'] = df.groupby('ID').apply(lambda x: x.expanding().apply(lambda y: y['time'] - y[y['result']==1].tail(1)['time']))

Подобные вещи не сработали, потому что .expanding (). Apply () возвращает ndarray, и не уверен, как с ними справиться.Мне нужно использовать expanding () и получить время последней строки в результате = 1, чтобы я мог вычесть из него время последней строки.Я не уверен, как это сделать.

Так как expanding (). Apply () возвращает ndarray, я пытался сделать из него фрейм данных, но, похоже, также есть ошибка и не уверен правильный подход.

def func(y):
    df = pd.DataFrame(y,columns=['ID','result','time_since_1'])
    # filter here
    # return one value (time_since_1)

df['time_since_1'] = df.groupby('ID').apply(lambda x: x.expanding().apply(lambda y: func(y))

Любые разные идеи или код помогают мне.Спасибо.

1 Ответ

0 голосов
/ 26 сентября 2019

Моя попытка не является ожидаемым решением, но, возможно, может помочь вам ...

r=df.groupby('ID').apply(lambda x: x.where(x['result'].eq(1))['time'].shift().ffill().fillna(df['time']))
df['time_since_1']=df['time']-r.reset_index().sort_values('level_1').set_index('level_1')['time']
print(df)
      ID  result  time  time_since_1
0   1234       0     1           0.0
1   1234       1     2           0.0
2   1234       0     3           1.0
3   2256       1     4           0.0
4   1234       0     5           3.0
5   1234       1     6           4.0
6   1234       0     7           1.0
7   2256       0     8           4.0
8   2256       1     9           5.0
9   2256       0    10           1.0
10  1234       1    11           5.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...