Fillna с обращенным вперед и назад условием в пандах

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

Поскольку это может быть непонятно, приведу пару примеров:

  col1                    
0 10    
1 10  
2 NaN
3 NaN
4 NaN
5 10
6 5
7 NaN
8 5
9 NaN
10 NaN
11 NaN
12 NaN
  • Значение в строке 2 имеет 10 в 1 строке, идущей назад, и 10 в 3 строках, идущей вперед. -> Заполнить 10
  • Значение в строке 3 имеет 10 в 2 строках назад и 10 в 2 строках вперед. -> Заполнить 10
  • Значение в строке 4 имеет 10 в 3-х строках назад и 10 в 1-й строке вперед. -> Заполнить 10
  • Значение в строке 7 включает 5 в 1 строке в обратном направлении и 5 в 1 строке при движении вперед. -> Заполнить 5
  • Значение в строке 9 имеет 5 в 1 строке, идущей назад, но не 5 в 3 строках, идущих вперед. -> Тогда не заполняйте

Тогда результат будет таким:

  col1                    
0 10    
1 10  
2 10
3 10
4 10
5 10
6 5
7 5
8 5
9 NaN
10 NaN
11 NaN
12 NaN

Могу ли я использовать какие-либо функции, чтобы передать эту логику fillna?

Спасибо!!


person Tomás Carrera de Souza    schedule 18.04.2020    source источник
comment
В документации к fillna() говорится, что метод поддерживает только ffill или backfill (также называемые pad и bfill соответственно). Вам придется реализовать функцию, чтобы решить проблему самостоятельно.   -  person Erik André    schedule 18.04.2020


Ответы (1)


Вы можете сравнить прямое заполнение и обратное заполнение Series с параметром limit, маску цепочки с & для побитового И только для строк с пропущенными значениями и заменить его столбцом прямого заполнения:

m1 = df['col1'].isna()
f = df['col1'].ffill(limit=3)
m2 = f.eq(df['col1'].bfill(limit=3))

df['col2'] = df['col1'].mask(m1 & m2, f)
print (df)
    col1  col2
0   10.0  10.0
1   10.0  10.0
2    NaN  10.0
3    NaN  10.0
4    NaN  10.0
5   10.0  10.0
6    5.0   5.0
7    NaN   5.0
8    5.0   5.0
9    NaN   NaN
10   NaN   NaN
11   NaN   NaN
12   NaN   NaN
person jezrael    schedule 18.04.2020
comment
Работал как шарм! Я не знал функции mask(). Спасибо. - person Tomás Carrera de Souza; 18.04.2020