Панды вменяют Null со средним значением предыдущего и следующего значения в строке - PullRequest
1 голос
/ 24 сентября 2019

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

В приведенном ниже примере я хотел бы вписать только Nan в 2-й ряд и столбец c2

import pandas as pd
import numpy as np

df = pd.DataFrame([[1, 2, 3, 4], [5,np.nan,np.nan,8], [9,np.nan,11,np.nan]], columns=['c1', 'c2', 'c3', 'c4'])

Out

   c1   c2    c3   c4
0   1  2.0   3.0  4.0
1   5  NaN   NaN  8.0
2   9  NaN  11.0  NaN

Воля становится

   c1   c2    c3   c4
0   1  2.0   3.0  4.0
1   5  NaN   NaN  8.0
2   9  10  11.0  NaN   <-- value 10 replaces Nan

1 Ответ

2 голосов
/ 24 сентября 2019

Используйте DataFrame.interpolate с параметрами axis=1 для обработки по строкам, limit_area='inside' для обработки NaN с значений, окруженных действительными значениями и limit=1 для заполненного максимума 1.

Существует также параметр по умолчанию limit_direction='forward', поэтому при замене большего числа значений NaN s только первым.Вы можете найти его по другому interpolate с limit_direction='backward' и протестировать пропущенные значения, использованные для замены после, по DataFrame.mask:

mask = df.interpolate(axis=1, limit_area='inside', limit=1, limit_direction='backward').isna()
df1 = df.interpolate(axis=1, limit_area='inside', limit=1).mask(mask)
print (df1)
    c1    c2    c3   c4
0  1.0   2.0   3.0  4.0
1  5.0   NaN   NaN  8.0
2  9.0  10.0  11.0  NaN

Detail :

print (df.interpolate(axis=1, limit_area='inside', limit=1))
    c1    c2    c3   c4
0  1.0   2.0   3.0  4.0
1  5.0   6.0   NaN  8.0
2  9.0  10.0  11.0  NaN

print (df.interpolate(axis=1, limit_area='inside', limit=1, limit_direction='backward'))
    c1    c2    c3   c4
0  1.0   2.0   3.0  4.0
1  5.0   NaN   7.0  8.0
2  9.0  10.0  11.0  NaN

Аналогичная идея заключается в использовании обратной заливки с limit=1 для пропущенных значений теста:

mask = df.bfill(axis=1, limit=1).isna()
df1 = df.interpolate(axis=1, limit_area='inside', limit=1).mask(mask)

Detail :

print (df.bfill(axis=1, limit=1))
    c1    c2    c3   c4
0  1.0   2.0   3.0  4.0
1  5.0   NaN   8.0  8.0
2  9.0  11.0  11.0  NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...