Эффективный метод для подсчета последовательных положительных значений в кадре данных панд - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь посчитать количество последовательных положительных событий для каждого столбца в кадре данных панд.Решение, предоставляемое DSM здесь - Подсчет последовательных положительных значений в массиве Python хорошо работает для данной серии.

import pandas as pd

a = [0,1,0,1,1,0,0,0,1,1,0,1,0]
b = [0,0,0,0,1,1,0,1,1,1,0,0,0]

series = pd.Series(a)

consecutiveCount(series).values

array ([0, 1, 0, 1,2, 0, 0, 0, 1, 2, 0, 1, 0], dtype = int64)

Однако, когда я пытаюсь сделать это для кадра данных с несколькими столбцами, я получаюследующий.

df = pd.DataFrame({'a':a, 'b':b})
consecutiveCount(df)

ValueError: Grouper for '<class 'pandas.core.frame.DataFrame'>' not 1-dimensional

Если я повторяю каждый столбец, он работает, но очень медленно.Есть ли векторизованный способ обработки всего фрейма данных сразу?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Используйте consecutiveCounts просто один раз в серии без стека .Затем вернитесь к фрейму данных.

Использование DSM consecutiveCount, которое я назвал здесь c для простоты:

>>> c = lambda y: y * (y.groupby((y != y.shift()).cumsum()).cumcount() + 1)
>>> c(df.unstack()).unstack().T

    a   b
0   0   0
1   1   0
2   0   0
3   1   0
4   2   1
5   0   2
6   0   0
7   0   1
8   1   2
9   2   3
10  0   0
11  1   0
12  0   0

Время

# df2 is (65, 40)
df2 = pd.concat([pd.concat([df]*20, axis=1)]*5).T.reset_index(drop=True).T.reset_index(drop=True)

%timeit c(df2.unstack()).unstack().T
5.54 ms ± 296 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df2.apply(c)
82.5 ms ± 2.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
0 голосов
/ 18 сентября 2018

Вы можете попробовать метод apply.Это может дать вам лучшие результаты:

df.apply(consecutiveCount)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...