Предыдущие N строк, пока не будет найдено значение, отличное от нуля

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

Данные

data = {'id_st': [100, 100, 100, 100, 100, 100, 100, 100, 100], 
    'year':  [2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018],
    'djma':  [1000, 2200, 0, 3000, 1000, 0, 2000, 0, 0],
    'taux': [np.nan, 0.9, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 0.7]}

df = pd.DataFrame(data) 
df

Предыдущие N строк, пока не будет найдено значение, отличное от нуля

df['prv_djma'] = df['djma'].shift()

Предыдущие N строк, пока не будет найдено значение, отличное от нуля

Что я ищу

Предыдущие N строк, пока не будет найдено значение, отличное от нуля

Цель состоит в том, чтобы проверить N строк назад, пока не будет найдено ненулевое значение djma, а затем поместить значение в текущую строку (столбец prv_djma).

Например, последняя строка с (индекс 8) имеет djma = 0, а (индекс 7) также djma = 0, поэтому я хочу заполнить столбец prv_djma с помощью djma (индекс 6).

Примечание

Проблема у меня в индексе 8. все остальные строки правильные.

Вы нажали «Отправить» до того, как закончили свой пост, или это все, что у вас есть?

cs95 20.06.2019 16:34

@ cs95 Я пытаюсь перефразировать свой вопрос, чтобы всем было понятно. Извините, если это вызывает проблемы

adil blanco 20.06.2019 16:55

@adilblanco, во-первых, пожалуйста, опубликуйте данные в виде текста (без изображений пожалуйста), во-вторых, вопрос не очень ясен, можете ли вы объяснить логику немного подробнее? Спасибо

anky 20.06.2019 17:18

@anky_91 anky_91 Я обновил свой вопрос, надеюсь, теперь все понятно. Спасибо

adil blanco 20.06.2019 17:50

Что бы вы хотели, чтобы в первых трех строках было 0 для djma? Должен ли вывод быть NaN NaN NaN 0 3000 для первых 5 строк?

ALollz 20.06.2019 18:02

@ALollz Спасибо за ответ. Моя конечная цель состоит в том, чтобы, когда у меня нет djma в течение года, я мог использовать тот, что был в предыдущие годы (ближайший год).

adil blanco 20.06.2019 18:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
6
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это shift, гарантирующее, что если есть последовательные 0, мы затем заполним предыдущее значение:

m = df.djma.eq(0)
df['prv_djma'] = df.djma.shift().mask((m == m.shift()) & m).ffill()

Выход:

   id_st  year  djma  taux  prev_djma
0    100  2010  1000   NaN        NaN
1    100  2011  2200   0.9     1000.0
2    100  2012     0   1.1     2200.0
3    100  2013  3000   1.2        0.0
4    100  2014  1000   1.3     3000.0
5    100  2015     0   1.4     1000.0
6    100  2016  2000   1.5        0.0
7    100  2017     0   1.6     2000.0
8    100  2018     0   0.7     2000.0

Для групп это нужно делать отдельно, чтобы .shift не вылилось за пределы группы.

def get_prv(x):
    m = x.eq(0)
    return x.shift().mask((m == m.shift()) & m).ffill()

df['prv_djma'] = df.groupby('id_st')['djma'].apply(get_prv)

Спасибо за ответ, в моем случае у меня много ['id_st'], я пробовал с groupby df['prv_djma'] = df.groupby('id_st')['djma'].shift().mask((m == m.shift()) & m).ffill(), но не работает ни одно предложение

adil blanco 20.06.2019 20:11

@adilblanco Посмотрите мое обновление, сделайте его функцией, а затем подайте заявку на groupby.

ALollz 20.06.2019 20:22

Другие вопросы по теме