Ускорение счетчика петель панд - PullRequest
0 голосов
/ 26 сентября 2018

Так что в настоящее время я обновляю счетчик строка за строкой в ​​pandas df, и я не думаю, что это самый быстрый способ сделать что-либо.

Ниже приведена упрощенная версия df, которую я используюУ меня есть два счетчика С1, считающие каждый день категории "S", и С2, подсчитывающие каждый раз, когда он переключается на "S" с "N", но не с "B" на "S", если только он не с "N" на "B", чтобы"S".

Это делается с помощью циклов for и if, но довольно медленно работает с 1,7 миллионами строк.Я проделал немалый поиск и, похоже, не могу найти более подход «панды / нуди».

Любые идеи или указатели в правильном направлении будут высоко оценены.

  Date  Category C1 C2
1/1/2015    N   0   0
1/2/2015    N   0   0
1/5/2015    S   1   1
1/5/2015    S   2   1
1/6/2015    S   3   1
1/6/2015    S   4   1
1/7/2015    N   4   1
1/7/2015    N   4   1
1/12/2015   N   4   1
1/12/2015   N   4   1
1/13/2015   N   4   1
1/13/2015   S   5   2
1/15/2015   S   6   2
1/15/2015   B   7   2
1/16/2015   S   8   2
1/16/2015   S   9   2
1/16/2015   N   8   2
1/21/2015   N   8   2
1/21/2015   S   9   3
1/22/2015   S   10  3

Ответы [ 2 ]

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

Вы можете справиться с этим только с одной петлей.Основным фокусом цикла является подсчет S, скажем, counter1.Внутри цикла for проверьте, является ли предыдущий N, если это так, добавьте к counter2.Иначе, если предыдущий - B, а предыдущий - N, добавьте к counter2.

Например, если у вас есть список категорий, вы делаете:

C1, C2 = 0, 0
for i in range(len(category)):
    if category[i] == 'S':
        C1 += 1
        if category[max(0, i-1)] =='N':
            C2 += 1
        elif (category[max(0, i-1)]=='B') and (category[max(0, i-2)]=='N'):
            C2 += 1

Сэто, вы можете минимизировать количество циклов for.Надеюсь, это поможет.

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

Как правило, вы хотите использовать .cumsum() для накопления значений и .shift(), когда хотите проверить предыдущие или следующие значения.Знание того, что True эквивалентно 1 в математических выражениях, экономит нам немного времени.

Для приведенных примеров значений будет работать следующее:

df['C1'] = (df['Category'] == 'S').cumsum()
df['C2'] = ((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')).cumsum()

Однакочасть с

не от "B" до "S", если только не от "N" до "B" до "S".

Делает последнее немногоболее сложныйОднако это должно быть возможно с немного более сложной настройкой:

df['C2'] = (((df['Category'] == 'S') & (df['Category'].shift(1) == 'N')) |
            ((df['Category'] == 'S') & (df['Category'].shift(1) == 'B') & (df['Category'].shift(2) == 'N'))).cumsum()

Предполагается, что единственными строками "от B до S", которые вы хотите считать, являются строки, где строка n-1 - это N, строка nэто B, а строка n + 1 это S. Все остальные экземпляры не будут включены.

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