Существует ли эффективный способ вычисления значений столбцов в Pandas с использованием значений из предыдущих строк на основе условных значений из других столбцов?

#python #pandas #dataframe #loops #vectorization

#python #pandas #dataframe #циклы #векторизация

Вопрос:

Рассмотрите возможность перебора моего фрейма данных:

 import pandas as pd

df = pd.DataFrame({
    'Price': [1000, 1000, 1000, 2000, 2000, 2000, 2000, 1400, 1400],
    'Count': [0, 0, 0, 0, 0, 0, 0, 0, 0]
})

for idx in df.index:
    if df['Price'].iloc[idx] > 1500:
        if idx > 0:
            df['Count'].iloc[idx] = df['Count'].iloc[idx - 1]   1
 

В результате:

Цена Количество
0 1000 0
1 1000 0
2 1000 0
3 2000 1
4 2000 2
5 2000 3
6 2000 4
7 1400 0
8 1400 0

Есть ли более эффективный способ сделать это?

Ответ №1:

Создайте псевдогруппы, используя Series.cumsum , затем используйте groupby.cumcount для генерации внутригрупповых подсчетов:

 groups = df.Price.le(1500).cumsum()
df['Count'] = df.Price.gt(1500).groupby(groups).cumcount()

#    Price  Count
# 0   1000      0
# 1   1000      0
# 2   1000      0
# 3   2000      1
# 4   2000      2
# 5   2000      3
# 6   2000      4
# 7   1400      0
# 8   1400      0
 

Ответ №2:

Используется mask для скрытия значений ниже 1500 и использования cumsum для создания счетчика:

 df['Count'] = df.mask(df['Price'] <= 1500)['Count'].add(1).cumsum().fillna(0).astype(int)
print(df)

# Output:
   Price  Count
0   1000      0
1   1000      0
2   1000      0
3   2000      1
4   2000      2
5   2000      3
6   2000      4
7   1400      0
8   1400      0
 

Комментарии:

1. Спасибо. Ваше решение работает на моем примере. Однако, если вы добавите еще две строки в мой фрейм данных с Price 3000 и 3000, ваше решение продолжит считать 5, 6. Мне нужно начать сначала с 1, 2.